|
REPORT Z_ABAPGIT.
SELECTION-SCREEN BEGIN OF SCREEN 1001.
SELECTION-SCREEN END OF SCREEN 1001.
CLASS zcx_abapgit_2fa_error DEFINITION
inheriting from CX_STATIC_CHECK
create public .
public section.
data MV_TEXT type STRING read-only .
methods CONSTRUCTOR
importing
!TEXTID like TEXTID optional
!PREVIOUS like PREVIOUS optional
!MV_TEXT type STRING optional .
methods IF_MESSAGE~GET_TEXT
redefinition .
protected section.
methods GET_DEFAULT_TEXT
returning
value(RV_TEXT) type STRING .
private section.
ENDCLASS.
CLASS ZCX_ABAPGIT_2FA_ERROR IMPLEMENTATION.
method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR
EXPORTING
TEXTID = TEXTID
PREVIOUS = PREVIOUS
.
me->MV_TEXT = MV_TEXT .
endmethod.
METHOD get_default_text.
rv_text = 'Error in two factor authentication.' ##NO_TEXT.
ENDMETHOD.
METHOD if_message~get_text.
IF mv_text IS NOT INITIAL.
result = mv_text.
ELSEIF get_default_text( ) IS NOT INITIAL.
result = get_default_text( ).
ELSE.
result = super->get_text( ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS zcx_abapgit_2fa_auth_failed DEFINITION
inheriting from ZCX_ABAPGIT_2FA_ERROR
final
create public .
public section.
methods CONSTRUCTOR
importing
!TEXTID like TEXTID optional
!PREVIOUS like PREVIOUS optional
!MV_TEXT type STRING optional .
protected section.
methods GET_DEFAULT_TEXT
redefinition .
private section.
ENDCLASS.
CLASS ZCX_ABAPGIT_2FA_AUTH_FAILED IMPLEMENTATION.
method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR
EXPORTING
TEXTID = TEXTID
PREVIOUS = PREVIOUS
MV_TEXT = MV_TEXT
.
endmethod.
METHOD get_default_text.
rv_text = 'Authentication failed using 2FA.' ##NO_TEXT.
ENDMETHOD.
ENDCLASS.
CLASS zcx_abapgit_2fa_comm_error DEFINITION
inheriting from ZCX_ABAPGIT_2FA_ERROR
final
create public .
public section.
methods CONSTRUCTOR
importing
!TEXTID like TEXTID optional
!PREVIOUS like PREVIOUS optional
!MV_TEXT type STRING optional .
protected section.
methods GET_DEFAULT_TEXT
redefinition .
private section.
ENDCLASS.
CLASS ZCX_ABAPGIT_2FA_COMM_ERROR IMPLEMENTATION.
method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR
EXPORTING
TEXTID = TEXTID
PREVIOUS = PREVIOUS
MV_TEXT = MV_TEXT
.
endmethod.
METHOD get_default_text.
rv_text = 'Communication error.' ##NO_TEXT.
ENDMETHOD.
ENDCLASS.
CLASS zcx_abapgit_2fa_del_failed DEFINITION
inheriting from ZCX_ABAPGIT_2FA_ERROR
final
create public .
public section.
methods CONSTRUCTOR
importing
!TEXTID like TEXTID optional
!PREVIOUS like PREVIOUS optional
!MV_TEXT type STRING optional .
protected section.
methods GET_DEFAULT_TEXT
redefinition .
private section.
ENDCLASS.
CLASS ZCX_ABAPGIT_2FA_DEL_FAILED IMPLEMENTATION.
method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR
EXPORTING
TEXTID = TEXTID
PREVIOUS = PREVIOUS
MV_TEXT = MV_TEXT
.
endmethod.
METHOD get_default_text.
rv_text = 'Deleting previous access tokens failed.' ##NO_TEXT.
ENDMETHOD.
ENDCLASS.
CLASS zcx_abapgit_2fa_gen_failed DEFINITION
inheriting from ZCX_ABAPGIT_2FA_ERROR
final
create public .
public section.
methods CONSTRUCTOR
importing
!TEXTID like TEXTID optional
!PREVIOUS like PREVIOUS optional
!MV_TEXT type STRING optional .
protected section.
methods GET_DEFAULT_TEXT
redefinition .
private section.
ENDCLASS.
CLASS ZCX_ABAPGIT_2FA_GEN_FAILED IMPLEMENTATION.
method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR
EXPORTING
TEXTID = TEXTID
PREVIOUS = PREVIOUS
MV_TEXT = MV_TEXT
.
endmethod.
METHOD get_default_text.
rv_text = 'Two factor access token generation failed.' ##NO_TEXT.
ENDMETHOD.
ENDCLASS.
CLASS zcx_abapgit_2fa_illegal_state DEFINITION
inheriting from ZCX_ABAPGIT_2FA_ERROR
final
create public .
public section.
methods CONSTRUCTOR
importing
!TEXTID like TEXTID optional
!PREVIOUS like PREVIOUS optional
!MV_TEXT type STRING optional .
protected section.
methods GET_DEFAULT_TEXT
redefinition .
private section.
ENDCLASS.
CLASS ZCX_ABAPGIT_2FA_ILLEGAL_STATE IMPLEMENTATION.
method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR
EXPORTING
TEXTID = TEXTID
PREVIOUS = PREVIOUS
MV_TEXT = MV_TEXT
.
endmethod.
METHOD get_default_text.
rv_text = 'Illegal state.' ##NO_TEXT.
ENDMETHOD.
ENDCLASS.
CLASS zcx_abapgit_2fa_unsupported DEFINITION
inheriting from ZCX_ABAPGIT_2FA_ERROR
final
create public .
public section.
methods CONSTRUCTOR
importing
!TEXTID like TEXTID optional
!PREVIOUS like PREVIOUS optional
!MV_TEXT type STRING optional .
protected section.
methods GET_DEFAULT_TEXT
redefinition .
private section.
ENDCLASS.
CLASS ZCX_ABAPGIT_2FA_UNSUPPORTED IMPLEMENTATION.
method CONSTRUCTOR.
CALL METHOD SUPER->CONSTRUCTOR
EXPORTING
TEXTID = TEXTID
PREVIOUS = PREVIOUS
MV_TEXT = MV_TEXT
.
endmethod.
METHOD get_default_text.
rv_text = 'The service is not supported for two factor authentication.' ##NO_TEXT.
ENDMETHOD.
ENDCLASS.
CLASS zcx_abapgit_cancel DEFINITION
INHERITING FROM cx_static_check
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcx_abapgit_cancel IMPLEMENTATION.
ENDCLASS.
"! abapGit general error
CLASS zcx_abapgit_exception DEFINITION
INHERITING FROM cx_static_check
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES:
if_t100_message.
CLASS-METHODS:
"! Raise exception with text
"! @parameter iv_text | Text
"! @parameter ix_previous | Previous exception
"! @raising zcx_abapgit_exception | Exception
raise IMPORTING iv_text TYPE clike
ix_previous TYPE REF TO cx_root OPTIONAL
RAISING zcx_abapgit_exception,
"! Raise exception with T100 message
"! <p>
"! Will default to sy-msg* variables. These need to be set right before calling this method.
"! </p>
"! @parameter iv_msgid | Message ID
"! @parameter iv_msgno | Message number
"! @parameter iv_msgv1 | Message variable 1
"! @parameter iv_msgv2 | Message variable 2
"! @parameter iv_msgv3 | Message variable 3
"! @parameter iv_msgv4 | Message variable 4
"! @raising zcx_abapgit_exception | Exception
raise_t100 IMPORTING VALUE(iv_msgid) TYPE symsgid DEFAULT sy-msgid
VALUE(iv_msgno) TYPE symsgno DEFAULT sy-msgno
VALUE(iv_msgv1) TYPE symsgv DEFAULT sy-msgv1
VALUE(iv_msgv2) TYPE symsgv DEFAULT sy-msgv2
VALUE(iv_msgv3) TYPE symsgv DEFAULT sy-msgv3
VALUE(iv_msgv4) TYPE symsgv DEFAULT sy-msgv4
RAISING zcx_abapgit_exception .
METHODS:
constructor IMPORTING textid LIKE if_t100_message=>t100key OPTIONAL
previous LIKE previous OPTIONAL
msgv1 TYPE symsgv OPTIONAL
msgv2 TYPE symsgv OPTIONAL
msgv3 TYPE symsgv OPTIONAL
msgv4 TYPE symsgv OPTIONAL.
DATA:
subrc TYPE sysubrc READ-ONLY,
msgv1 TYPE symsgv READ-ONLY,
msgv2 TYPE symsgv READ-ONLY,
msgv3 TYPE symsgv READ-ONLY,
msgv4 TYPE symsgv READ-ONLY.
PROTECTED SECTION.
PRIVATE SECTION.
CONSTANTS:
gc_generic_error_msg TYPE string VALUE `An error occured (ZCX_ABAPGIT_EXCEPTION)` ##NO_TEXT.
ENDCLASS.
CLASS zcx_abapgit_exception IMPLEMENTATION.
METHOD constructor ##ADT_SUPPRESS_GENERATION.
super->constructor( previous = previous ).
me->msgv1 = msgv1.
me->msgv2 = msgv2.
me->msgv3 = msgv3.
me->msgv4 = msgv4.
CLEAR me->textid.
IF textid IS INITIAL.
if_t100_message~t100key = if_t100_message=>default_textid.
ELSE.
if_t100_message~t100key = textid.
ENDIF.
ENDMETHOD.
METHOD raise.
DATA: lv_msgv1 TYPE symsgv,
lv_msgv2 TYPE symsgv,
lv_msgv3 TYPE symsgv,
lv_msgv4 TYPE symsgv,
ls_t100_key TYPE scx_t100key,
lv_text TYPE string.
IF iv_text IS INITIAL.
lv_text = gc_generic_error_msg.
ELSE.
lv_text = iv_text.
ENDIF.
cl_message_helper=>set_msg_vars_for_clike( lv_text ).
ls_t100_key-msgid = sy-msgid.
ls_t100_key-msgno = sy-msgno.
ls_t100_key-attr1 = 'MSGV1'.
ls_t100_key-attr2 = 'MSGV2'.
ls_t100_key-attr3 = 'MSGV3'.
ls_t100_key-attr4 = 'MSGV4'.
lv_msgv1 = sy-msgv1.
lv_msgv2 = sy-msgv2.
lv_msgv3 = sy-msgv3.
lv_msgv4 = sy-msgv4.
RAISE EXCEPTION TYPE zcx_abapgit_exception
EXPORTING
textid = ls_t100_key
msgv1 = lv_msgv1
msgv2 = lv_msgv2
msgv3 = lv_msgv3
msgv4 = lv_msgv4
previous = ix_previous.
ENDMETHOD.
METHOD raise_t100.
DATA: ls_t100_key TYPE scx_t100key.
ls_t100_key-msgid = iv_msgid.
ls_t100_key-msgno = iv_msgno.
ls_t100_key-attr1 = 'MSGV1'.
ls_t100_key-attr2 = 'MSGV2'.
ls_t100_key-attr3 = 'MSGV3'.
ls_t100_key-attr4 = 'MSGV4'.
IF iv_msgid IS INITIAL.
CLEAR ls_t100_key.
ENDIF.
RAISE EXCEPTION TYPE zcx_abapgit_exception
EXPORTING
textid = ls_t100_key
msgv1 = iv_msgv1
msgv2 = iv_msgv2
msgv3 = iv_msgv3
msgv4 = iv_msgv4.
ENDMETHOD.
ENDCLASS.
CLASS zcx_abapgit_not_found DEFINITION
INHERITING FROM cx_static_check
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcx_abapgit_not_found IMPLEMENTATION.
ENDCLASS.
INTERFACE zif_abapgit_version DEFERRED.
INTERFACE zif_abapgit_tadir DEFERRED.
INTERFACE zif_abapgit_sap_package DEFERRED.
INTERFACE zif_abapgit_repo_srv DEFERRED.
INTERFACE zif_abapgit_gui_page_hotkey DEFERRED.
INTERFACE zif_abapgit_git_operations DEFERRED.
INTERFACE zif_abapgit_exit DEFERRED.
INTERFACE zif_abapgit_ecatt DEFERRED.
INTERFACE zif_abapgit_dot_abapgit DEFERRED.
INTERFACE zif_abapgit_definitions DEFERRED.
INTERFACE zif_abapgit_code_inspector DEFERRED.
INTERFACE zif_abapgit_branch_overview DEFERRED.
INTERFACE zif_abapgit_auth DEFERRED.
INTERFACE zif_abapgit_tag_popups DEFERRED.
INTERFACE zif_abapgit_popups DEFERRED.
INTERFACE zif_abapgit_gui_page DEFERRED.
INTERFACE zif_abapgit_persistence DEFERRED.
INTERFACE zif_abapgit_persist_user DEFERRED.
INTERFACE zif_abapgit_persist_repo DEFERRED.
INTERFACE zif_abapgit_oo_object_fnc DEFERRED.
INTERFACE zif_abapgit_object_enhs DEFERRED.
INTERFACE zif_abapgit_object_enho DEFERRED.
INTERFACE zif_abapgit_object DEFERRED.
INTERFACE zif_abapgit_comparison_result DEFERRED.
INTERFACE zif_abapgit_2fa_authenticator DEFERRED.
INTERFACE zif_abapgit_background DEFERRED.
CLASS zcl_abapgit_zlib_stream DEFINITION DEFERRED.
CLASS zcl_abapgit_zlib_huffman DEFINITION DEFERRED.
CLASS zcl_abapgit_zlib_convert DEFINITION DEFERRED.
CLASS zcl_abapgit_zlib DEFINITION DEFERRED.
CLASS zcl_abapgit_zip DEFINITION DEFERRED.
CLASS zcl_abapgit_transport_objects DEFINITION DEFERRED.
CLASS zcl_abapgit_transport_2_branch DEFINITION DEFERRED.
CLASS zcl_abapgit_transport DEFINITION DEFERRED.
CLASS zcl_abapgit_tadir DEFINITION DEFERRED.
CLASS zcl_abapgit_syntax_check DEFINITION DEFERRED.
CLASS zcl_abapgit_stage_logic DEFINITION DEFERRED.
CLASS zcl_abapgit_stage DEFINITION DEFERRED.
CLASS zcl_abapgit_skip_objects DEFINITION DEFERRED.
CLASS zcl_abapgit_settings DEFINITION DEFERRED.
CLASS zcl_abapgit_sap_package DEFINITION DEFERRED.
CLASS zcl_abapgit_repo_srv DEFINITION DEFERRED.
CLASS zcl_abapgit_repo_online DEFINITION DEFERRED.
CLASS zcl_abapgit_repo_offline DEFINITION DEFERRED.
CLASS zcl_abapgit_repo_content_list DEFINITION DEFERRED.
CLASS zcl_abapgit_repo DEFINITION DEFERRED.
CLASS zcl_abapgit_objects_bridge DEFINITION DEFERRED.
CLASS zcl_abapgit_objects DEFINITION DEFERRED.
CLASS zcl_abapgit_news DEFINITION DEFERRED.
CLASS zcl_abapgit_migrations DEFINITION DEFERRED.
CLASS zcl_abapgit_merge DEFINITION DEFERRED.
CLASS zcl_abapgit_injector DEFINITION DEFERRED.
CLASS zcl_abapgit_http_client DEFINITION DEFERRED.
CLASS zcl_abapgit_folder_logic DEFINITION DEFERRED.
CLASS zcl_abapgit_file_status DEFINITION DEFERRED.
CLASS zcl_abapgit_factory DEFINITION DEFERRED.
CLASS zcl_abapgit_exit DEFINITION DEFERRED.
CLASS zcl_abapgit_dot_abapgit DEFINITION DEFERRED.
CLASS zcl_abapgit_dependencies DEFINITION DEFERRED.
CLASS zcl_abapgit_default_transport DEFINITION DEFERRED.
CLASS zcl_abapgit_code_inspector DEFINITION DEFERRED.
CLASS zcl_abapgit_branch_overview DEFINITION DEFERRED.
CLASS zcl_abapgit_auth DEFINITION DEFERRED.
CLASS zcl_abapgit_xml_pretty DEFINITION DEFERRED.
CLASS zcl_abapgit_xml_output DEFINITION DEFERRED.
CLASS zcl_abapgit_xml_input DEFINITION DEFERRED.
CLASS zcl_abapgit_xml DEFINITION DEFERRED.
CLASS zcl_abapgit_user_master_record DEFINITION DEFERRED.
CLASS zcl_abapgit_url DEFINITION DEFERRED.
CLASS zcl_abapgit_time DEFINITION DEFERRED.
CLASS zcl_abapgit_state DEFINITION DEFERRED.
CLASS zcl_abapgit_requirement_helper DEFINITION DEFERRED.
CLASS zcl_abapgit_progress DEFINITION DEFERRED.
CLASS zcl_abapgit_path DEFINITION DEFERRED.
CLASS zcl_abapgit_login_manager DEFINITION DEFERRED.
CLASS zcl_abapgit_log DEFINITION DEFERRED.
CLASS zcl_abapgit_language DEFINITION DEFERRED.
CLASS zcl_abapgit_hash DEFINITION DEFERRED.
CLASS zcl_abapgit_diff DEFINITION DEFERRED.
CLASS zcl_abapgit_convert DEFINITION DEFERRED.
CLASS zcl_abapgit_ui_injector DEFINITION DEFERRED.
CLASS zcl_abapgit_ui_factory DEFINITION DEFERRED.
CLASS zcl_abapgit_tag_popups DEFINITION DEFERRED.
CLASS zcl_abapgit_services_repo DEFINITION DEFERRED.
CLASS zcl_abapgit_services_git DEFINITION DEFERRED.
CLASS zcl_abapgit_services_abapgit DEFINITION DEFERRED.
CLASS zcl_abapgit_popups DEFINITION DEFERRED.
CLASS zcl_abapgit_password_dialog DEFINITION DEFERRED.
CLASS zcl_abapgit_html_toolbar DEFINITION DEFERRED.
CLASS zcl_abapgit_html_action_utils DEFINITION DEFERRED.
CLASS zcl_abapgit_html DEFINITION DEFERRED.
CLASS zcl_abapgit_hotkeys DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_view_tutorial DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_view_repo DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_router DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_tag DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_syntax DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_stage DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_settings DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_repo_sett DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_repo_over DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_merge_res DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_merge DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_main DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_explore DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_diff DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_debuginfo DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_commit DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_code_insp DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_boverview DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_bkg_run DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_bkg DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_chunk_lib DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_asset_manager DEFINITION DEFERRED.
CLASS zcl_abapgit_gui DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_db_edit DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_db_dis DEFINITION DEFERRED.
CLASS zcl_abapgit_gui_page_db DEFINITION DEFERRED.
CLASS zcl_abapgit_test_serialize DEFINITION DEFERRED.
CLASS zcl_abapgit_syntax_xml DEFINITION DEFERRED.
CLASS zcl_abapgit_syntax_highlighter DEFINITION DEFERRED.
CLASS zcl_abapgit_syntax_abap DEFINITION DEFERRED.
CLASS zcl_abapgit_persistence_user DEFINITION DEFERRED.
CLASS zcl_abapgit_persistence_repo DEFINITION DEFERRED.
CLASS zcl_abapgit_persistence_db DEFINITION DEFERRED.
CLASS zcl_abapgit_persist_settings DEFINITION DEFERRED.
CLASS zcl_abapgit_persist_migrate DEFINITION DEFERRED.
CLASS zcl_abapgit_persist_injector DEFINITION DEFERRED.
CLASS zcl_abapgit_persist_factory DEFINITION DEFERRED.
CLASS zcl_abapgit_persist_background DEFINITION DEFERRED.
CLASS zcl_abapgit_oo_serializer DEFINITION DEFERRED.
CLASS zcl_abapgit_oo_interface DEFINITION DEFERRED.
CLASS zcl_abapgit_oo_factory DEFINITION DEFERRED.
CLASS zcl_abapgit_oo_class_new DEFINITION DEFERRED.
CLASS zcl_abapgit_oo_class DEFINITION DEFERRED.
CLASS zcl_abapgit_oo_base DEFINITION DEFERRED.
CLASS zcl_abapgit_objects_super DEFINITION DEFERRED.
CLASS zcl_abapgit_objects_saxx_super DEFINITION DEFERRED.
CLASS zcl_abapgit_objects_program DEFINITION DEFERRED.
CLASS zcl_abapgit_objects_generic DEFINITION DEFERRED.
CLASS zcl_abapgit_objects_files DEFINITION DEFERRED.
CLASS zcl_abapgit_objects_activation DEFINITION DEFERRED.
CLASS zcl_abapgit_object_xslt DEFINITION DEFERRED.
CLASS zcl_abapgit_object_xinx DEFINITION DEFERRED.
CLASS zcl_abapgit_object_webi DEFINITION DEFERRED.
CLASS zcl_abapgit_object_wdyn DEFINITION DEFERRED.
CLASS zcl_abapgit_object_wdya DEFINITION DEFERRED.
CLASS zcl_abapgit_object_wapa DEFINITION DEFERRED.
CLASS zcl_abapgit_object_w3super DEFINITION DEFERRED.
CLASS zcl_abapgit_object_w3mi DEFINITION DEFERRED.
CLASS zcl_abapgit_object_w3ht DEFINITION DEFERRED.
CLASS zcl_abapgit_object_view DEFINITION DEFERRED.
CLASS zcl_abapgit_object_vcls DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ucsa DEFINITION DEFERRED.
CLASS zcl_abapgit_object_type DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ttyp DEFINITION DEFERRED.
CLASS zcl_abapgit_object_tran DEFINITION DEFERRED.
CLASS zcl_abapgit_object_tobj DEFINITION DEFERRED.
CLASS zcl_abapgit_object_tabl_valid DEFINITION DEFERRED.
CLASS zcl_abapgit_object_tabl_dialog DEFINITION DEFERRED.
CLASS zcl_abapgit_object_tabl DEFINITION DEFERRED.
CLASS zcl_abapgit_object_sxci DEFINITION DEFERRED.
CLASS zcl_abapgit_object_suso DEFINITION DEFERRED.
CLASS zcl_abapgit_object_susc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_styl DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ssst DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ssfo DEFINITION DEFERRED.
CLASS zcl_abapgit_object_srfc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_splo DEFINITION DEFERRED.
CLASS zcl_abapgit_object_smim DEFINITION DEFERRED.
CLASS zcl_abapgit_object_sicf DEFINITION DEFERRED.
CLASS zcl_abapgit_object_shma DEFINITION DEFERRED.
CLASS zcl_abapgit_object_shlp DEFINITION DEFERRED.
CLASS zcl_abapgit_object_shi8 DEFINITION DEFERRED.
CLASS zcl_abapgit_object_shi5 DEFINITION DEFERRED.
CLASS zcl_abapgit_object_shi3 DEFINITION DEFERRED.
CLASS zcl_abapgit_object_sfsw DEFINITION DEFERRED.
CLASS zcl_abapgit_object_sfpi DEFINITION DEFERRED.
CLASS zcl_abapgit_object_sfpf DEFINITION DEFERRED.
CLASS zcl_abapgit_object_sfbs DEFINITION DEFERRED.
CLASS zcl_abapgit_object_sfbf DEFINITION DEFERRED.
CLASS zcl_abapgit_object_scp1 DEFINITION DEFERRED.
CLASS zcl_abapgit_object_sapc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_samc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_prog DEFINITION DEFERRED.
CLASS zcl_abapgit_object_prag DEFINITION DEFERRED.
CLASS zcl_abapgit_object_pinf DEFINITION DEFERRED.
CLASS zcl_abapgit_object_para DEFINITION DEFERRED.
CLASS zcl_abapgit_object_nrob DEFINITION DEFERRED.
CLASS zcl_abapgit_object_msag DEFINITION DEFERRED.
CLASS zcl_abapgit_object_jobd DEFINITION DEFERRED.
CLASS zcl_abapgit_object_intf DEFINITION DEFERRED.
CLASS zcl_abapgit_object_iext DEFINITION DEFERRED.
CLASS zcl_abapgit_object_idoc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_iatu DEFINITION DEFERRED.
CLASS zcl_abapgit_object_iasp DEFINITION DEFERRED.
CLASS zcl_abapgit_object_iarp DEFINITION DEFERRED.
CLASS zcl_abapgit_object_iamu DEFINITION DEFERRED.
CLASS zcl_abapgit_object_fugr DEFINITION DEFERRED.
CLASS zcl_abapgit_object_form DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ensc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enqu DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enhs_hook_d DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enhs_badi_d DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enhs DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho_wdyn DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho_wdyc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho_intf DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho_hook DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho_fugr DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho_clif DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho_class DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho_badi DEFINITION DEFERRED.
CLASS zcl_abapgit_object_enho DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ecvo DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ectd DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ectc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ecsp DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ecsd DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ecatt_super DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ecat DEFINITION DEFERRED.
CLASS zcl_abapgit_object_dtel DEFINITION DEFERRED.
CLASS zcl_abapgit_object_dsys DEFINITION DEFERRED.
CLASS zcl_abapgit_object_doma DEFINITION DEFERRED.
CLASS zcl_abapgit_object_docv DEFINITION DEFERRED.
CLASS zcl_abapgit_object_doct DEFINITION DEFERRED.
CLASS zcl_abapgit_object_dial DEFINITION DEFERRED.
CLASS zcl_abapgit_object_devc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ddlx DEFINITION DEFERRED.
CLASS zcl_abapgit_object_ddls DEFINITION DEFERRED.
CLASS zcl_abapgit_object_dcls DEFINITION DEFERRED.
CLASS zcl_abapgit_object_cus2 DEFINITION DEFERRED.
CLASS zcl_abapgit_object_cus1 DEFINITION DEFERRED.
CLASS zcl_abapgit_object_cus0 DEFINITION DEFERRED.
CLASS zcl_abapgit_object_cmpt DEFINITION DEFERRED.
CLASS zcl_abapgit_object_clas_old DEFINITION DEFERRED.
CLASS zcl_abapgit_object_clas_new DEFINITION DEFERRED.
CLASS zcl_abapgit_object_clas DEFINITION DEFERRED.
CLASS zcl_abapgit_object_char DEFINITION DEFERRED.
CLASS zcl_abapgit_object_avas DEFINITION DEFERRED.
CLASS zcl_abapgit_object_auth DEFINITION DEFERRED.
CLASS zcl_abapgit_object_asfc DEFINITION DEFERRED.
CLASS zcl_abapgit_object_acid DEFINITION DEFERRED.
CLASS zcl_abapgit_comparison_null DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_val_obj_upl DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_val_obj_down DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_system_upl DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_system_downl DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_sp_upload DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_sp_download DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_script_upl DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_script_downl DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_helper DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_data_upload DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_data_downl DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_config_upl DEFINITION DEFERRED.
CLASS zcl_abapgit_ecatt_config_downl DEFINITION DEFERRED.
CLASS zcl_abapgit_proxy_config DEFINITION DEFERRED.
CLASS zcl_abapgit_proxy_auth DEFINITION DEFERRED.
CLASS zcl_abapgit_http_digest DEFINITION DEFERRED.
CLASS zcl_abapgit_http DEFINITION DEFERRED.
CLASS zcl_abapgit_2fa_github_auth DEFINITION DEFERRED.
CLASS zcl_abapgit_2fa_auth_registry DEFINITION DEFERRED.
CLASS zcl_abapgit_2fa_auth_base DEFINITION DEFERRED.
CLASS zcl_abapgit_tag DEFINITION DEFERRED.
CLASS zcl_abapgit_git_utils DEFINITION DEFERRED.
CLASS zcl_abapgit_git_transport DEFINITION DEFERRED.
CLASS zcl_abapgit_git_porcelain DEFINITION DEFERRED.
CLASS zcl_abapgit_git_pack DEFINITION DEFERRED.
CLASS zcl_abapgit_git_branch_list DEFINITION DEFERRED.
CLASS zcl_abapgit_background_push_fi DEFINITION DEFERRED.
CLASS zcl_abapgit_background_push_au DEFINITION DEFERRED.
CLASS zcl_abapgit_background_pull DEFINITION DEFERRED.
CLASS zcl_abapgit_background DEFINITION DEFERRED.
INTERFACE zif_abapgit_background
.
TYPES:
BEGIN OF ty_settings,
key TYPE string,
value TYPE string,
END OF ty_settings .
TYPES:
ty_settings_tt TYPE STANDARD TABLE OF ty_settings WITH DEFAULT KEY .
CLASS-METHODS get_description
RETURNING
VALUE(rv_description) TYPE string .
CLASS-METHODS get_settings
CHANGING
VALUE(ct_settings) TYPE ty_settings_tt .
METHODS run
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
!io_log TYPE REF TO zcl_abapgit_log
!it_settings TYPE ty_settings_tt OPTIONAL
RAISING
zcx_abapgit_exception .
ENDINTERFACE.
"! Defines a two factor authentication authenticator
"! <p>
"! Authenticators support one or multiple services and are able to generate access tokens using the
"! service's API using the users username, password and two factor authentication token
"! (app/sms/tokengenerator). With these access tokens the user can be authenticated to the service's
"! implementation of the git http api, just like the "normal" password would.
"! </p>
"! <p>
"! <em>LCL_2FA_AUTHENTICATOR_REGISTRY</em> can be used to find a suitable implementation for a given
"! repository.
"! </p>
"! <p>
"! Using the <em>begin</em> and <em>end</em> methods an internal session can be started and
"! completed in which internal state necessary for multiple methods will be cached. This can be
"! used to avoid having multiple http sessions between <em>authenticate</em> and
"! <em>delete_access_tokens</em>.
"! </p>
INTERFACE zif_abapgit_2fa_authenticator
.
"! Generate an access token
"! @parameter iv_url | Repository url
"! @parameter iv_username | Username
"! @parameter iv_password | Password
"! @parameter iv_2fa_token | Two factor token
"! @parameter rv_access_token | Generated access token
"! @raising lcx_2fa_auth_failed | Authentication failed
"! @raising lcx_2fa_token_gen_failed | Token generation failed
METHODS authenticate
IMPORTING
!iv_url TYPE string
!iv_username TYPE string
!iv_password TYPE string
!iv_2fa_token TYPE string
RETURNING
VALUE(rv_access_token) TYPE string
RAISING
zcx_abapgit_2fa_auth_failed
zcx_abapgit_2fa_gen_failed
zcx_abapgit_2fa_comm_error .
"! Check if this authenticator instance supports the give repository url
"! @parameter iv_url | Repository url
"! @parameter rv_supported | Is supported
METHODS supports_url
IMPORTING
!iv_url TYPE string
RETURNING
VALUE(rv_supported) TYPE abap_bool .
"! Check if two factor authentication is required
"! @parameter iv_url | Repository url
"! @parameter iv_username | Username
"! @parameter iv_password | Password
"! @parameter rv_required | 2FA is required
METHODS is_2fa_required
IMPORTING
!iv_url TYPE string
!iv_username TYPE string
!iv_password TYPE string
RETURNING
VALUE(rv_required) TYPE abap_bool
RAISING
zcx_abapgit_2fa_comm_error .
"! Delete all previously created access tokens for abapGit
"! @parameter iv_url | Repository url
"! @parameter iv_username | Username
"! @parameter iv_password | Password
"! @parameter iv_2fa_token | Two factor token
"! @raising lcx_2fa_token_del_failed | Token deletion failed
"! @raising lcx_2fa_auth_failed | Authentication failed
METHODS delete_access_tokens
IMPORTING
!iv_url TYPE string
!iv_username TYPE string
!iv_password TYPE string
!iv_2fa_token TYPE string
RAISING
zcx_abapgit_2fa_del_failed
zcx_abapgit_2fa_comm_error
zcx_abapgit_2fa_auth_failed .
"! Begin an authenticator session that uses internal caching for authorizations
"! @raising lcx_2fa_illegal_state | Session already started
METHODS begin
RAISING
zcx_abapgit_2fa_illegal_state .
"! End an authenticator session and clear internal caches
"! @raising lcx_2fa_illegal_state | Session not running
METHODS end
RAISING
zcx_abapgit_2fa_illegal_state .
ENDINTERFACE.
INTERFACE zif_abapgit_comparison_result.
METHODS:
show_confirmation_dialog,
is_result_complete_halt
RETURNING VALUE(rv_response) TYPE abap_bool.
ENDINTERFACE.
INTERFACE zif_abapgit_object_enho.
METHODS:
deserialize
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
iv_package TYPE devclass
RAISING zcx_abapgit_exception,
serialize
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
ii_enh_tool TYPE REF TO if_enh_tool
RAISING zcx_abapgit_exception.
ENDINTERFACE.
INTERFACE zif_abapgit_object_enhs.
METHODS:
deserialize
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
iv_package TYPE devclass
ii_enh_spot_tool TYPE REF TO if_enh_spot_tool
RAISING zcx_abapgit_exception,
serialize
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
ii_enh_spot_tool TYPE REF TO if_enh_spot_tool
RAISING zcx_abapgit_exception.
ENDINTERFACE.
INTERFACE zif_abapgit_gui_page.
METHODS on_event
IMPORTING iv_action TYPE clike
iv_prev_page TYPE clike
iv_getdata TYPE clike OPTIONAL
it_postdata TYPE cnht_post_data_tab OPTIONAL
EXPORTING ei_page TYPE REF TO zif_abapgit_gui_page
ev_state TYPE i
RAISING zcx_abapgit_exception zcx_abapgit_cancel.
METHODS render
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
ENDINTERFACE.
INTERFACE zif_abapgit_auth.
TYPES: ty_authorization TYPE string.
CONSTANTS: BEGIN OF gc_authorization,
uninstall TYPE ty_authorization VALUE 'UNINSTALL',
transport_to_branch TYPE ty_authorization VALUE 'TRANSPORT_TO_BRANCH',
update_local_checksum TYPE ty_authorization VALUE 'UPDATE_LOCAL_CHECKSUM',
END OF gc_authorization.
METHODS:
is_allowed
IMPORTING iv_authorization TYPE ty_authorization
iv_param TYPE string OPTIONAL
RETURNING VALUE(rv_allowed) TYPE abap_bool.
ENDINTERFACE.
INTERFACE zif_abapgit_code_inspector
.
METHODS:
run
RETURNING
VALUE(rt_list) TYPE scit_alvlist
RAISING
zcx_abapgit_exception,
get_inspection
RETURNING
VALUE(ro_inspection) TYPE REF TO cl_ci_inspection.
ENDINTERFACE.
INTERFACE zif_abapgit_definitions.
TYPES:
ty_type TYPE c LENGTH 6 .
TYPES:
ty_bitbyte TYPE c LENGTH 8 .
TYPES:
ty_sha1 TYPE c LENGTH 40 .
TYPES: ty_adler32 TYPE x LENGTH 4.
TYPES:
BEGIN OF ty_file_signature,
path TYPE string,
filename TYPE string,
sha1 TYPE zif_abapgit_definitions=>ty_sha1,
END OF ty_file_signature .
TYPES:
ty_file_signatures_tt TYPE STANDARD TABLE OF
ty_file_signature WITH DEFAULT KEY .
TYPES:
ty_file_signatures_ts TYPE SORTED TABLE OF
ty_file_signature WITH UNIQUE KEY path filename .
TYPES:
BEGIN OF ty_file.
INCLUDE TYPE ty_file_signature.
TYPES: data TYPE xstring,
END OF ty_file .
TYPES:
ty_files_tt TYPE STANDARD TABLE OF ty_file WITH DEFAULT KEY .
TYPES:
ty_string_tt TYPE STANDARD TABLE OF string WITH DEFAULT KEY .
TYPES: ty_repo_ref_tt TYPE STANDARD TABLE OF REF TO zcl_abapgit_repo WITH DEFAULT KEY.
TYPES ty_git_branch_type TYPE char2 .
TYPES:
BEGIN OF ty_git_branch,
sha1 TYPE zif_abapgit_definitions=>ty_sha1,
name TYPE string,
type TYPE ty_git_branch_type,
is_head TYPE abap_bool,
display_name TYPE string,
END OF ty_git_branch .
TYPES:
ty_git_branch_list_tt TYPE STANDARD TABLE OF ty_git_branch WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_git_tag,
sha1 TYPE zif_abapgit_definitions=>ty_sha1,
object TYPE zif_abapgit_definitions=>ty_sha1,
name TYPE string,
type TYPE ty_git_branch_type,
display_name TYPE string,
tagger_name TYPE string,
tagger_email TYPE string,
message TYPE string,
body TYPE string,
END OF ty_git_tag .
TYPES:
ty_git_tag_list_tt TYPE STANDARD TABLE OF ty_git_tag WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_hotkey,
sequence TYPE string,
action TYPE string,
END OF ty_hotkey,
tty_hotkey TYPE STANDARD TABLE OF ty_hotkey
WITH NON-UNIQUE DEFAULT KEY.
CONSTANTS:
BEGIN OF c_git_branch_type,
branch TYPE ty_git_branch_type VALUE 'HD',
lightweight_tag TYPE ty_git_branch_type VALUE 'TG',
annotated_tag TYPE ty_git_branch_type VALUE 'AT',
other TYPE ty_git_branch_type VALUE 'ZZ',
END OF c_git_branch_type .
CONSTANTS c_head_name TYPE string VALUE 'HEAD' ##NO_TEXT.
TYPES:
BEGIN OF ty_git_user,
name TYPE string,
email TYPE string,
END OF ty_git_user .
TYPES:
BEGIN OF ty_comment,
committer TYPE ty_git_user,
author TYPE ty_git_user,
comment TYPE string,
END OF ty_comment .
TYPES:
BEGIN OF ty_item,
obj_type TYPE tadir-object,
obj_name TYPE tadir-obj_name,
devclass TYPE devclass,
END OF ty_item .
TYPES:
ty_items_tt TYPE STANDARD TABLE OF ty_item WITH DEFAULT KEY .
TYPES:
ty_items_ts TYPE SORTED TABLE OF ty_item WITH UNIQUE KEY obj_type obj_name .
TYPES:
BEGIN OF ty_file_item,
file TYPE zif_abapgit_definitions=>ty_file,
item TYPE ty_item,
END OF ty_file_item .
TYPES:
ty_files_item_tt TYPE STANDARD TABLE OF ty_file_item WITH DEFAULT KEY .
TYPES: ty_yes_no TYPE c LENGTH 1.
TYPES: BEGIN OF ty_overwrite.
INCLUDE TYPE ty_item.
TYPES: decision TYPE ty_yes_no,
END OF ty_overwrite.
TYPES: ty_overwrite_tt TYPE STANDARD TABLE OF ty_overwrite WITH DEFAULT KEY.
TYPES: BEGIN OF ty_requirements,
met TYPE ty_yes_no,
decision TYPE ty_yes_no,
END OF ty_requirements.
TYPES: BEGIN OF ty_transport_type,
request TYPE trfunction,
task TYPE trfunction,
END OF ty_transport_type.
TYPES: BEGIN OF ty_transport,
required TYPE abap_bool,
transport TYPE trkorr,
type TYPE ty_transport_type,
END OF ty_transport.
TYPES: BEGIN OF ty_deserialize_checks,
overwrite TYPE ty_overwrite_tt,
warning_package TYPE ty_overwrite_tt,
requirements TYPE ty_requirements,
transport TYPE ty_transport,
END OF ty_deserialize_checks,
BEGIN OF ty_delete_checks,
transport TYPE ty_transport,
END OF ty_delete_checks.
TYPES:
BEGIN OF ty_metadata,
class TYPE string,
version TYPE string,
late_deser TYPE abap_bool,
delete_tadir TYPE abap_bool,
ddic TYPE abap_bool,
END OF ty_metadata .
TYPES:
BEGIN OF ty_web_asset,
url TYPE w3url,
base64 TYPE string,
content TYPE xstring,
END OF ty_web_asset .
TYPES:
tt_web_assets TYPE STANDARD TABLE OF ty_web_asset WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_repo_file,
path TYPE string,
filename TYPE string,
is_changed TYPE abap_bool,
rstate TYPE char1,
lstate TYPE char1,
END OF ty_repo_file .
TYPES:
tt_repo_files TYPE STANDARD TABLE OF ty_repo_file WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_stage_files,
local TYPE zif_abapgit_definitions=>ty_files_item_tt,
remote TYPE zif_abapgit_definitions=>ty_files_tt,
END OF ty_stage_files .
TYPES:
ty_chmod TYPE c LENGTH 6 .
TYPES:
BEGIN OF ty_object,
sha1 TYPE zif_abapgit_definitions=>ty_sha1,
type TYPE zif_abapgit_definitions=>ty_type,
data TYPE xstring,
adler32 TYPE ty_adler32,
index TYPE i,
END OF ty_object .
TYPES:
ty_objects_tt TYPE STANDARD TABLE OF ty_object WITH DEFAULT KEY
WITH NON-UNIQUE SORTED KEY sha COMPONENTS sha1
WITH NON-UNIQUE SORTED KEY type COMPONENTS type sha1.
TYPES:
BEGIN OF ty_tadir,
pgmid TYPE tadir-pgmid,
object TYPE tadir-object,
obj_name TYPE tadir-obj_name,
devclass TYPE tadir-devclass,
korrnum TYPE tadir-korrnum,
delflag TYPE tadir-delflag,
path TYPE string,
END OF ty_tadir .
TYPES:
ty_tadir_tt TYPE STANDARD TABLE OF ty_tadir WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_result,
obj_type TYPE tadir-object,
obj_name TYPE tadir-obj_name,
path TYPE string,
filename TYPE string,
package TYPE devclass,
match TYPE sap_bool,
lstate TYPE char1,
rstate TYPE char1,
END OF ty_result .
TYPES:
ty_results_tt TYPE STANDARD TABLE OF ty_result WITH DEFAULT KEY .
TYPES:
ty_sval_tt TYPE STANDARD TABLE OF sval WITH DEFAULT KEY .
TYPES:
ty_seocompotx_tt TYPE STANDARD TABLE OF seocompotx WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_tpool.
INCLUDE TYPE textpool.
TYPES: split TYPE c LENGTH 8.
TYPES: END OF ty_tpool .
TYPES:
ty_tpool_tt TYPE STANDARD TABLE OF ty_tpool WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_sotr,
header TYPE sotr_head,
entries TYPE sotr_text_tt,
END OF ty_sotr .
TYPES:
ty_sotr_tt TYPE STANDARD TABLE OF ty_sotr WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_transport_to_branch,
branch_name TYPE string,
commit_text TYPE string,
END OF ty_transport_to_branch .
TYPES: BEGIN OF ty_create,
name TYPE string,
parent TYPE string,
END OF ty_create.
TYPES: BEGIN OF ty_commit,
sha1 TYPE ty_sha1,
parent1 TYPE ty_sha1,
parent2 TYPE ty_sha1,
author TYPE string,
email TYPE string,
time TYPE string,
message TYPE string,
branch TYPE string,
merge TYPE string,
tags TYPE stringtab,
create TYPE STANDARD TABLE OF ty_create WITH DEFAULT KEY,
compressed TYPE abap_bool,
END OF ty_commit.
TYPES: ty_commit_tt TYPE STANDARD TABLE OF ty_commit WITH DEFAULT KEY.
CONSTANTS: BEGIN OF c_diff,
insert TYPE c LENGTH 1 VALUE 'I',
delete TYPE c LENGTH 1 VALUE 'D',
update TYPE c LENGTH 1 VALUE 'U',
END OF c_diff.
TYPES: BEGIN OF ty_diff,
new_num TYPE c LENGTH 6,
new TYPE string,
result TYPE c LENGTH 1,
old_num TYPE c LENGTH 6,
old TYPE string,
short TYPE abap_bool,
beacon TYPE i,
END OF ty_diff.
TYPES: ty_diffs_tt TYPE STANDARD TABLE OF ty_diff WITH DEFAULT KEY.
TYPES: BEGIN OF ty_count,
insert TYPE i,
delete TYPE i,
update TYPE i,
END OF ty_count.
TYPES:
BEGIN OF ty_expanded,
path TYPE string,
name TYPE string,
sha1 TYPE ty_sha1,
chmod TYPE ty_chmod,
END OF ty_expanded .
TYPES:
ty_expanded_tt TYPE STANDARD TABLE OF ty_expanded WITH DEFAULT KEY .
TYPES: BEGIN OF ty_ancestor,
commit TYPE ty_sha1,
tree TYPE ty_sha1,
time TYPE string,
body TYPE string,
END OF ty_ancestor.
TYPES: BEGIN OF ty_merge,
repo TYPE REF TO zcl_abapgit_repo_online,
source TYPE ty_git_branch,
target TYPE ty_git_branch,
common TYPE ty_ancestor,
stree TYPE ty_expanded_tt,
ttree TYPE ty_expanded_tt,
ctree TYPE ty_expanded_tt,
result TYPE ty_expanded_tt,
stage TYPE REF TO zcl_abapgit_stage,
conflict TYPE string,
END OF ty_merge.
TYPES: BEGIN OF ty_merge_conflict,
path TYPE string,
filename TYPE string,
source_sha1 TYPE zif_abapgit_definitions=>ty_sha1,
source_data TYPE xstring,
target_sha1 TYPE zif_abapgit_definitions=>ty_sha1,
target_data TYPE xstring,
result_sha1 TYPE zif_abapgit_definitions=>ty_sha1,
result_data TYPE xstring,
END OF ty_merge_conflict,
tt_merge_conflict TYPE STANDARD TABLE OF ty_merge_conflict WITH DEFAULT KEY.
TYPES: BEGIN OF ty_repo_item,
obj_type TYPE tadir-object,
obj_name TYPE tadir-obj_name,
sortkey TYPE i,
path TYPE string,
is_dir TYPE abap_bool,
changes TYPE i,
lstate TYPE char1,
rstate TYPE char1,
files TYPE tt_repo_files,
END OF ty_repo_item.
TYPES tt_repo_items TYPE STANDARD TABLE OF ty_repo_item WITH DEFAULT KEY.
TYPES: BEGIN OF ty_s_user_settings,
max_lines TYPE i,
adt_jump_enabled TYPE abap_bool,
show_default_repo TYPE abap_bool,
link_hints_enabled TYPE abap_bool,
link_hint_key TYPE char01,
link_hint_background_color TYPE string,
hotkeys TYPE tty_hotkey,
END OF ty_s_user_settings.
CONSTANTS:
BEGIN OF c_type,
commit TYPE zif_abapgit_definitions=>ty_type VALUE 'commit', "#EC NOTEXT
tree TYPE zif_abapgit_definitions=>ty_type VALUE 'tree', "#EC NOTEXT
ref_d TYPE zif_abapgit_definitions=>ty_type VALUE 'ref_d', "#EC NOTEXT
tag TYPE zif_abapgit_definitions=>ty_type VALUE 'tag', "#EC NOTEXT
blob TYPE zif_abapgit_definitions=>ty_type VALUE 'blob', "#EC NOTEXT
END OF c_type .
CONSTANTS:
BEGIN OF c_state, " https://git-scm.com/docs/git-status
unchanged TYPE char1 VALUE '',
added TYPE char1 VALUE 'A',
modified TYPE char1 VALUE 'M',
deleted TYPE char1 VALUE 'D', "For future use
mixed TYPE char1 VALUE '*',
END OF c_state .
CONSTANTS:
BEGIN OF c_chmod,
file TYPE ty_chmod VALUE '100644',
executable TYPE ty_chmod VALUE '100755',
dir TYPE ty_chmod VALUE '40000 ',
END OF c_chmod .
CONSTANTS:
BEGIN OF c_event_state,
not_handled VALUE 0,
re_render VALUE 1,
new_page VALUE 2,
go_back VALUE 3,
no_more_act VALUE 4,
new_page_w_bookmark VALUE 5,
go_back_to_bookmark VALUE 6,
new_page_replacing VALUE 7,
END OF c_event_state .
CONSTANTS:
BEGIN OF c_html_opt,
strong TYPE c VALUE 'E',
cancel TYPE c VALUE 'C',
crossout TYPE c VALUE 'X',
END OF c_html_opt .
CONSTANTS:
BEGIN OF c_action_type,
sapevent TYPE c VALUE 'E',
url TYPE c VALUE 'U',
onclick TYPE c VALUE 'C',
separator TYPE c VALUE 'S',
dummy TYPE c VALUE '_',
END OF c_action_type .
CONSTANTS c_crlf TYPE abap_cr_lf VALUE cl_abap_char_utilities=>cr_lf ##NO_TEXT.
CONSTANTS c_newline TYPE abap_char1 VALUE cl_abap_char_utilities=>newline ##NO_TEXT.
CONSTANTS c_english TYPE spras VALUE 'E' ##NO_TEXT.
CONSTANTS c_root_dir TYPE string VALUE '/' ##NO_TEXT.
CONSTANTS c_dot_abapgit TYPE string VALUE '.abapgit.xml' ##NO_TEXT.
CONSTANTS c_author_regex TYPE string VALUE '^([\\\w\s\.\,\#@\-_1-9\(\) ]+) <(.*)> (\d{10})\s?.\d{4}$' ##NO_TEXT.
CONSTANTS:
BEGIN OF c_action,
repo_refresh TYPE string VALUE 'repo_refresh',
repo_remove TYPE string VALUE 'repo_remove',
repo_settings TYPE string VALUE 'repo_settings',
repo_purge TYPE string VALUE 'repo_purge',
repo_newonline TYPE string VALUE 'repo_newonline',
repo_newoffline TYPE string VALUE 'repo_newoffline',
repo_remote_attach TYPE string VALUE 'repo_remote_attach',
repo_remote_detach TYPE string VALUE 'repo_remote_detach',
repo_remote_change TYPE string VALUE 'repo_remote_change',
repo_refresh_checksums TYPE string VALUE 'repo_refresh_checksums',
repo_toggle_fav TYPE string VALUE 'repo_toggle_fav',
repo_transport_to_branch TYPE string VALUE 'repo_transport_to_branch',
repo_syntax_check TYPE string VALUE 'repo_syntax_check',
repo_code_inspector TYPE string VALUE 'repo_code_inspector',
abapgit_home TYPE string VALUE 'abapgit_home',
abapgit_install TYPE string VALUE 'abapgit_install',
zip_import TYPE string VALUE 'zip_import',
zip_export TYPE string VALUE 'zip_export',
zip_package TYPE string VALUE 'zip_package',
zip_transport TYPE string VALUE 'zip_transport',
zip_object TYPE string VALUE 'zip_object',
git_pull TYPE string VALUE 'git_pull',
git_reset TYPE string VALUE 'git_reset',
git_branch_create TYPE string VALUE 'git_branch_create',
git_branch_switch TYPE string VALUE 'git_branch_switch',
git_branch_delete TYPE string VALUE 'git_branch_delete',
git_tag_create TYPE string VALUE 'git_tag_create',
git_tag_delete TYPE string VALUE 'git_tag_delete',
git_tag_switch TYPE string VALUE 'git_tag_switch',
git_commit TYPE string VALUE 'git_commit',
db_display TYPE string VALUE 'db_display',
db_edit TYPE string VALUE 'db_edit',
bg_update TYPE string VALUE 'bg_update',
go_main TYPE string VALUE 'go_main',
go_explore TYPE string VALUE 'go_explore',
go_repo_overview TYPE string VALUE 'go_repo_overview',
go_db TYPE string VALUE 'go_db',
go_background TYPE string VALUE 'go_background',
go_background_run TYPE string VALUE 'go_background_run',
go_diff TYPE string VALUE 'go_diff',
go_stage TYPE string VALUE 'go_stage',
go_commit TYPE string VALUE 'go_commit',
go_branch_overview TYPE string VALUE 'go_branch_overview',
go_tag_overview TYPE string VALUE 'go_tag_overview',
go_playground TYPE string VALUE 'go_playground',
go_debuginfo TYPE string VALUE 'go_debuginfo',
go_settings TYPE string VALUE 'go_settings',
go_tutorial TYPE string VALUE 'go_tutorial',
jump TYPE string VALUE 'jump',
jump_pkg TYPE string VALUE 'jump_pkg',
END OF c_action .
CONSTANTS:
BEGIN OF c_version,
active TYPE r3state VALUE 'A',
inactive TYPE r3state VALUE 'I',
END OF c_version .
CONSTANTS c_tag_prefix TYPE string VALUE 'refs/tags/' ##NO_TEXT.
ENDINTERFACE.
INTERFACE zif_abapgit_object.
METHODS:
serialize
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING zcx_abapgit_exception,
deserialize
IMPORTING iv_package TYPE devclass
io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING zcx_abapgit_exception,
delete
RAISING zcx_abapgit_exception,
exists
RETURNING VALUE(rv_bool) TYPE abap_bool
RAISING zcx_abapgit_exception,
is_locked
RETURNING VALUE(rv_is_locked) type abap_bool
RAISING
zcx_abapgit_exception,
changed_by
RETURNING VALUE(rv_user) TYPE xubname
RAISING zcx_abapgit_exception,
jump
RAISING zcx_abapgit_exception,
get_metadata
RETURNING VALUE(rs_metadata) TYPE zif_abapgit_definitions=>ty_metadata,
has_changed_since
IMPORTING iv_timestamp TYPE timestamp
RETURNING VALUE(rv_changed) TYPE abap_bool
RAISING zcx_abapgit_exception.
METHODS:
compare_to_remote_version
IMPORTING io_remote_version_xml TYPE REF TO zcl_abapgit_xml_input
RETURNING VALUE(ro_comparison_result) TYPE REF TO zif_abapgit_comparison_result
RAISING zcx_abapgit_exception.
DATA: mo_files TYPE REF TO zcl_abapgit_objects_files.
ENDINTERFACE.
INTERFACE zif_abapgit_oo_object_fnc.
TYPES: BEGIN OF ty_includes,
programm TYPE programm,
END OF ty_includes,
ty_includes_tt TYPE STANDARD TABLE OF ty_includes WITH DEFAULT KEY.
METHODS:
create
IMPORTING
iv_package TYPE devclass
iv_overwrite TYPE seox_boolean DEFAULT seox_true
CHANGING
cg_properties TYPE any
RAISING
zcx_abapgit_exception,
generate_locals
IMPORTING
is_key TYPE seoclskey
iv_force TYPE seox_boolean DEFAULT seox_true
it_local_definitions TYPE seop_source_string OPTIONAL
it_local_implementations TYPE seop_source_string OPTIONAL
it_local_macros TYPE seop_source_string OPTIONAL
it_local_test_classes TYPE seop_source_string OPTIONAL
RAISING
zcx_abapgit_exception,
deserialize_source
IMPORTING
is_key TYPE seoclskey
it_source TYPE zif_abapgit_definitions=>ty_string_tt
RAISING
zcx_abapgit_exception
cx_sy_dyn_call_error,
insert_text_pool
IMPORTING
iv_class_name TYPE seoclsname
it_text_pool TYPE textpool_table
iv_language TYPE spras
RAISING
zcx_abapgit_exception,
update_descriptions
IMPORTING
is_key TYPE seoclskey
it_descriptions TYPE zif_abapgit_definitions=>ty_seocompotx_tt,
add_to_activation_list
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
RAISING
zcx_abapgit_exception,
create_sotr
IMPORTING
iv_package TYPE devclass
it_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt
RAISING
zcx_abapgit_exception,
create_documentation
IMPORTING
it_lines TYPE tlinetab
iv_object_name TYPE dokhl-object
iv_language TYPE spras
RAISING
zcx_abapgit_exception,
get_includes
IMPORTING
iv_object_name TYPE sobj_name
RETURNING
VALUE(rt_includes) TYPE ty_includes_tt
RAISING
zcx_abapgit_exception,
exists
IMPORTING
is_object_name TYPE seoclskey
RETURNING
VALUE(rv_exists) TYPE abap_bool,
serialize_abap
IMPORTING
is_class_key TYPE seoclskey
iv_type TYPE seop_include_ext_app OPTIONAL
RETURNING
VALUE(rt_source) TYPE zif_abapgit_definitions=>ty_string_tt
RAISING
zcx_abapgit_exception
cx_sy_dyn_call_error,
get_skip_test_classes
RETURNING
VALUE(rv_skip) TYPE abap_bool,
get_class_properties
IMPORTING
is_class_key TYPE seoclskey
RETURNING
VALUE(rs_class_properties) TYPE vseoclass
RAISING
zcx_abapgit_exception,
get_interface_properties
IMPORTING
is_interface_key TYPE seoclskey
RETURNING
VALUE(rs_interface_properties) TYPE vseointerf
RAISING
zcx_abapgit_exception,
read_text_pool
IMPORTING
iv_class_name TYPE seoclsname
iv_language TYPE spras
RETURNING
VALUE(rt_text_pool) TYPE textpool_table,
read_documentation
IMPORTING
iv_class_name TYPE seoclsname
iv_language TYPE spras
RETURNING
VALUE(rt_lines) TYPE tlinetab,
read_sotr
IMPORTING
iv_object_name TYPE sobj_name
RETURNING
VALUE(rt_sotr) TYPE zif_abapgit_definitions=>ty_sotr_tt
RAISING
zcx_abapgit_exception,
read_descriptions
IMPORTING
iv_obejct_name TYPE seoclsname
RETURNING
VALUE(rt_descriptions) TYPE zif_abapgit_definitions=>ty_seocompotx_tt,
delete
IMPORTING
is_deletion_key TYPE seoclskey
RAISING
zcx_abapgit_exception,
read_superclass
IMPORTING
iv_classname TYPE seoclsname
RETURNING
VALUE(rv_superclass) TYPE seoclsname.
ENDINTERFACE.
INTERFACE zif_abapgit_popups
.
TYPES:
BEGIN OF ty_popup,
url TYPE string,
package TYPE devclass,
branch_name TYPE string,
cancel TYPE abap_bool,
END OF ty_popup .
CONSTANTS c_new_branch_label TYPE string VALUE '+ create new ...' ##NO_TEXT.
METHODS popup_package_export
EXPORTING
!ev_package TYPE devclass
!ev_folder_logic TYPE string
RAISING
zcx_abapgit_exception .
METHODS popup_folder_logic
RETURNING
VALUE(rv_folder_logic) TYPE string
RAISING
zcx_abapgit_exception .
METHODS popup_object
RETURNING
VALUE(rs_tadir) TYPE zif_abapgit_definitions=>ty_tadir
RAISING
zcx_abapgit_exception .
METHODS create_branch_popup
EXPORTING
!ev_name TYPE string
!ev_cancel TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS run_page_class_popup
EXPORTING
!ev_name TYPE string
!ev_cancel TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS repo_new_offline
RETURNING
VALUE(rs_popup) TYPE zif_abapgit_popups=>ty_popup
RAISING
zcx_abapgit_exception .
METHODS branch_list_popup
IMPORTING
!iv_url TYPE string
!iv_default_branch TYPE string OPTIONAL
!iv_show_new_option TYPE abap_bool OPTIONAL
RETURNING
VALUE(rs_branch) TYPE zif_abapgit_definitions=>ty_git_branch
RAISING
zcx_abapgit_exception .
METHODS repo_popup
IMPORTING
!iv_url TYPE string
!iv_package TYPE devclass OPTIONAL
!iv_branch TYPE string DEFAULT 'refs/heads/master'
!iv_freeze_package TYPE abap_bool OPTIONAL
!iv_freeze_url TYPE abap_bool OPTIONAL
!iv_title TYPE clike DEFAULT 'New Online Project'
RETURNING
VALUE(rs_popup) TYPE zif_abapgit_popups=>ty_popup
RAISING
zcx_abapgit_exception ##NO_TEXT.
METHODS popup_to_confirm
IMPORTING
!iv_titlebar TYPE clike
!iv_text_question TYPE clike
!iv_text_button_1 TYPE clike DEFAULT 'Yes'
!iv_icon_button_1 TYPE icon-name DEFAULT space
!iv_text_button_2 TYPE clike DEFAULT 'No'
!iv_icon_button_2 TYPE icon-name DEFAULT space
!iv_default_button TYPE char1 DEFAULT '1'
!iv_display_cancel_button TYPE char1 DEFAULT abap_true
RETURNING
VALUE(rv_answer) TYPE char1
RAISING
zcx_abapgit_exception .
METHODS popup_to_inform
IMPORTING
!iv_titlebar TYPE clike
!iv_text_message TYPE clike
RAISING
zcx_abapgit_exception .
METHODS popup_to_create_package
EXPORTING
!es_package_data TYPE scompkdtln
!ev_create TYPE boolean
RAISING
zcx_abapgit_exception .
METHODS popup_to_create_transp_branch
IMPORTING
!it_transport_headers TYPE trwbo_request_headers
RETURNING
VALUE(rs_transport_branch) TYPE zif_abapgit_definitions=>ty_transport_to_branch
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
METHODS popup_to_select_transports
RETURNING
VALUE(rt_trkorr) TYPE trwbo_request_headers .
METHODS popup_to_select_from_list
IMPORTING
!it_list TYPE STANDARD TABLE
!iv_header_text TYPE csequence
!iv_select_column_text TYPE csequence
!it_columns_to_display TYPE stringtab
EXPORTING
VALUE(et_list) TYPE STANDARD TABLE
RAISING
zcx_abapgit_cancel
zcx_abapgit_exception .
METHODS branch_popup_callback
IMPORTING
!iv_code TYPE clike
CHANGING
!ct_fields TYPE zif_abapgit_definitions=>ty_sval_tt
!cs_error TYPE svale
!cv_show_popup TYPE char01
RAISING
zcx_abapgit_exception .
METHODS package_popup_callback
IMPORTING
!iv_code TYPE clike
CHANGING
!ct_fields TYPE zif_abapgit_definitions=>ty_sval_tt
!cs_error TYPE svale
!cv_show_popup TYPE char01
RAISING
zcx_abapgit_exception .
METHODS popup_transport_request
IMPORTING
!is_transport_type TYPE zif_abapgit_definitions=>ty_transport_type
RETURNING
VALUE(rv_transport) TYPE trkorr
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
ENDINTERFACE.
INTERFACE zif_abapgit_tag_popups
.
METHODS:
tag_list_popup
IMPORTING
io_repo TYPE REF TO zcl_abapgit_repo_online
RETURNING
VALUE(rs_tag) TYPE zif_abapgit_definitions=>ty_git_tag
RAISING
zcx_abapgit_exception,
tag_select_popup
IMPORTING
io_repo TYPE REF TO zcl_abapgit_repo_online
RETURNING
VALUE(rs_tag) TYPE zif_abapgit_definitions=>ty_git_tag
RAISING
zcx_abapgit_exception .
ENDINTERFACE.
INTERFACE zif_abapgit_branch_overview
.
METHODS:
get_branches
RETURNING VALUE(rt_branches) TYPE zif_abapgit_definitions=>ty_git_branch_list_tt,
get_tags
RETURNING VALUE(rt_tags) TYPE zif_abapgit_definitions=>ty_git_tag_list_tt,
get_commits
RETURNING
VALUE(rt_commits) TYPE zif_abapgit_definitions=>ty_commit_tt,
compress
IMPORTING it_commits TYPE zif_abapgit_definitions=>ty_commit_tt
RETURNING VALUE(rt_commits) TYPE zif_abapgit_definitions=>ty_commit_tt
RAISING zcx_abapgit_exception.
ENDINTERFACE.
INTERFACE zif_abapgit_dot_abapgit.
TYPES:
BEGIN OF ty_requirement,
component TYPE dlvunit,
min_release TYPE saprelease,
min_patch TYPE sappatchlv,
END OF ty_requirement .
TYPES:
ty_requirement_tt TYPE STANDARD TABLE OF ty_requirement WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_dot_abapgit,
master_language TYPE spras,
starting_folder TYPE string,
folder_logic TYPE string,
ignore TYPE STANDARD TABLE OF string WITH DEFAULT KEY,
requirements TYPE ty_requirement_tt,
END OF ty_dot_abapgit .
CONSTANTS:
BEGIN OF c_folder_logic,
prefix TYPE string VALUE 'PREFIX',
full TYPE string VALUE 'FULL',
END OF c_folder_logic .
ENDINTERFACE.
INTERFACE zif_abapgit_persistence.
TYPES:
ty_type TYPE c LENGTH 12 .
TYPES:
ty_value TYPE c LENGTH 12 .
TYPES:
BEGIN OF ty_content,
type TYPE ty_type,
value TYPE ty_value,
data_str TYPE string,
END OF ty_content .
TYPES:
tt_content TYPE SORTED TABLE OF ty_content WITH UNIQUE KEY type value .
TYPES: BEGIN OF ty_local_checksum,
item TYPE zif_abapgit_definitions=>ty_item,
files TYPE zif_abapgit_definitions=>ty_file_signatures_tt,
END OF ty_local_checksum.
TYPES:
BEGIN OF ty_local_settings,
ignore_subpackages TYPE abap_bool,
write_protected TYPE abap_bool,
only_local_objects TYPE abap_bool,
code_inspector_check_variant TYPE sci_chkv,
block_commit TYPE abap_bool,
END OF ty_local_settings.
TYPES: ty_local_checksum_tt TYPE STANDARD TABLE OF ty_local_checksum WITH DEFAULT KEY.
TYPES: BEGIN OF ty_repo_xml,
url TYPE string,
branch_name TYPE string,
package TYPE devclass,
created_by TYPE xubname,
created_at TYPE timestampl,
deserialized_by TYPE xubname,
deserialized_at TYPE timestampl,
offline TYPE sap_bool,
local_checksums TYPE ty_local_checksum_tt,
dot_abapgit TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit,
head_branch TYPE string, " HEAD symref of the repo, master branch
local_settings TYPE ty_local_settings,
END OF ty_repo_xml.
TYPES: BEGIN OF ty_repo,
key TYPE zif_abapgit_persistence=>ty_value.
INCLUDE TYPE ty_repo_xml.
TYPES: END OF ty_repo.
TYPES: tt_repo TYPE STANDARD TABLE OF ty_repo WITH DEFAULT KEY.
TYPES: tt_repo_keys TYPE STANDARD TABLE OF ty_repo-key WITH DEFAULT KEY.
ENDINTERFACE.
INTERFACE zif_abapgit_persist_repo
.
METHODS add
IMPORTING
!iv_url TYPE string
!iv_branch_name TYPE string
!iv_branch TYPE zif_abapgit_definitions=>ty_sha1 OPTIONAL
!iv_package TYPE devclass
!iv_offline TYPE sap_bool DEFAULT abap_false
!is_dot_abapgit TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit
RETURNING
VALUE(rv_key) TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
METHODS delete
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
METHODS list
RETURNING
VALUE(rt_repos) TYPE zif_abapgit_persistence=>tt_repo
RAISING
zcx_abapgit_exception .
METHODS lock
IMPORTING
!iv_mode TYPE enqmode
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
METHODS read
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RETURNING
VALUE(rs_repo) TYPE zif_abapgit_persistence=>ty_repo
RAISING
zcx_abapgit_exception
zcx_abapgit_not_found .
METHODS update_branch_name
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!iv_branch_name TYPE zif_abapgit_persistence=>ty_repo_xml-branch_name
RAISING
zcx_abapgit_exception .
METHODS update_deserialized
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_value
!iv_deserialized_at TYPE timestampl
!iv_deserialized_by TYPE xubname
RAISING
zcx_abapgit_exception .
METHODS update_dot_abapgit
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!is_dot_abapgit TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit
RAISING
zcx_abapgit_exception .
METHODS update_head_branch
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!iv_head_branch TYPE zif_abapgit_persistence=>ty_repo_xml-head_branch
RAISING
zcx_abapgit_exception .
METHODS update_local_checksums
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!it_checksums TYPE zif_abapgit_persistence=>ty_repo_xml-local_checksums
RAISING
zcx_abapgit_exception .
METHODS update_local_settings
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!is_settings TYPE zif_abapgit_persistence=>ty_repo_xml-local_settings
RAISING
zcx_abapgit_exception .
METHODS update_offline
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!iv_offline TYPE zif_abapgit_persistence=>ty_repo_xml-offline
RAISING
zcx_abapgit_exception .
METHODS update_url
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!iv_url TYPE zif_abapgit_persistence=>ty_repo_xml-url
RAISING
zcx_abapgit_exception .
ENDINTERFACE.
INTERFACE zif_abapgit_persist_user
.
TYPES tt_favorites TYPE zif_abapgit_persistence=>tt_repo_keys .
METHODS get_changes_only
RETURNING
VALUE(rv_changes_only) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS get_default_git_user_email
RETURNING
VALUE(rv_email) TYPE string
RAISING
zcx_abapgit_exception .
METHODS get_default_git_user_name
RETURNING
VALUE(rv_username) TYPE string
RAISING
zcx_abapgit_exception .
METHODS get_diff_unified
RETURNING
VALUE(rv_diff_unified) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS get_favorites
RETURNING
VALUE(rt_favorites) TYPE tt_favorites
RAISING
zcx_abapgit_exception .
METHODS get_hide_files
RETURNING
VALUE(rv_hide) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS get_repo_git_user_email
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
RETURNING
VALUE(rv_email) TYPE string
RAISING
zcx_abapgit_exception .
METHODS get_repo_git_user_name
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
RETURNING
VALUE(rv_username) TYPE string
RAISING
zcx_abapgit_exception .
METHODS get_repo_last_change_seen
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
RETURNING
VALUE(rv_version) TYPE string
RAISING
zcx_abapgit_exception .
METHODS get_repo_login
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
RETURNING
VALUE(rv_login) TYPE string
RAISING
zcx_abapgit_exception .
METHODS get_repo_show
RETURNING
VALUE(rv_key) TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
METHODS is_favorite_repo
IMPORTING
!iv_repo_key TYPE zif_abapgit_persistence=>ty_repo-key
RETURNING
VALUE(rv_yes) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS set_default_git_user_email
IMPORTING
!iv_email TYPE string
RAISING
zcx_abapgit_exception .
METHODS set_default_git_user_name
IMPORTING
!iv_username TYPE string
RAISING
zcx_abapgit_exception .
METHODS set_repo_git_user_email
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
!iv_email TYPE string
RAISING
zcx_abapgit_exception .
METHODS set_repo_git_user_name
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
!iv_username TYPE string
RAISING
zcx_abapgit_exception .
METHODS set_repo_last_change_seen
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
!iv_version TYPE string
RAISING
zcx_abapgit_exception .
METHODS set_repo_login
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
!iv_login TYPE string
RAISING
zcx_abapgit_exception .
METHODS set_repo_show
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
METHODS toggle_changes_only
RETURNING
VALUE(rv_changes_only) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS toggle_diff_unified
RETURNING
VALUE(rv_diff_unified) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS toggle_favorite
IMPORTING
!iv_repo_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
METHODS toggle_hide_files
RETURNING
VALUE(rv_hide) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS get_settings
RETURNING
VALUE(rs_user_settings) TYPE zif_abapgit_definitions=>ty_s_user_settings
RAISING
zcx_abapgit_exception.
METHODS set_settings
IMPORTING
is_user_settings TYPE zif_abapgit_definitions=>ty_s_user_settings
RAISING
zcx_abapgit_exception.
ENDINTERFACE.
INTERFACE zif_abapgit_ecatt
.
" downport missing types
TYPES:
etvo_invert_validation TYPE c LENGTH 1,
etvo_error_prio TYPE n LENGTH 1,
etvo_impl_name TYPE c LENGTH 30,
etvo_impl_type TYPE c LENGTH 1,
etvo_impl_subtype TYPE c LENGTH 4,
etvo_package TYPE c LENGTH 255,
BEGIN OF etvoimpl_det,
impl_name TYPE etvo_impl_name,
impl_type TYPE etvo_impl_type,
impl_subtype TYPE etvo_impl_subtype,
impl_package TYPE etvo_package,
END OF etvoimpl_det.
TYPES:
BEGIN OF ecvo_bus_msg.
INCLUDE TYPE etobj_key.
TYPES:
bus_msg_no TYPE c LENGTH 1, " etvo_msg_no
arbgb TYPE arbgb,
msgnr TYPE msgnr,
bus_msg_text TYPE string, "etvo_bus_msg_text
otr_key TYPE sotr_conc,
msg_type TYPE c LENGTH 4, "etvo_msg_type
END OF ecvo_bus_msg,
etvo_bus_msg_tabtype TYPE STANDARD TABLE OF ecvo_bus_msg.
ENDINTERFACE.
INTERFACE zif_abapgit_exit.
TYPES:
ty_icm_sinfo2_tt TYPE STANDARD TABLE OF icm_sinfo2 WITH DEFAULT KEY.
METHODS:
change_local_host
CHANGING ct_hosts TYPE ty_icm_sinfo2_tt,
allow_sap_objects
RETURNING VALUE(rv_allowed) TYPE abap_bool,
change_proxy_url
IMPORTING iv_repo_url TYPE csequence
CHANGING cv_proxy_url TYPE string,
change_proxy_port
IMPORTING iv_repo_url TYPE csequence
CHANGING cv_proxy_port TYPE string,
change_proxy_authentication
IMPORTING iv_repo_url TYPE csequence
CHANGING cv_proxy_authentication TYPE abap_bool,
create_http_client
IMPORTING
iv_url TYPE string
RETURNING
VALUE(ri_client) TYPE REF TO if_http_client
RAISING
zcx_abapgit_exception,
http_client
IMPORTING
ii_client TYPE REF TO if_http_client,
change_tadir
IMPORTING
iv_package TYPE devclass
io_log TYPE REF TO zcl_abapgit_log
CHANGING
ct_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt.
ENDINTERFACE.
INTERFACE zif_abapgit_git_operations
.
METHODS push
IMPORTING
!is_comment TYPE zif_abapgit_definitions=>ty_comment
!io_stage TYPE REF TO zcl_abapgit_stage
RAISING
zcx_abapgit_exception .
METHODS create_branch
IMPORTING
!iv_name TYPE string
!iv_from TYPE zif_abapgit_definitions=>ty_sha1 OPTIONAL
RAISING
zcx_abapgit_exception .
ENDINTERFACE.
INTERFACE zif_abapgit_gui_page_hotkey
.
TYPES:
BEGIN OF ty_hotkey_action,
name TYPE string,
action TYPE string,
default_hotkey TYPE string,
END OF ty_hotkey_action,
tty_hotkey_action TYPE STANDARD TABLE OF ty_hotkey_action
WITH NON-UNIQUE DEFAULT KEY
WITH NON-UNIQUE SORTED KEY action
COMPONENTS action.
CLASS-METHODS
get_hotkey_actions
RETURNING
VALUE(rt_hotkey_actions) TYPE tty_hotkey_action.
ENDINTERFACE.
INTERFACE zif_abapgit_repo_srv
.
METHODS delete
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
RAISING
zcx_abapgit_exception .
METHODS get
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_value
RETURNING
VALUE(ro_repo) TYPE REF TO zcl_abapgit_repo
RAISING
zcx_abapgit_exception .
METHODS is_repo_installed
IMPORTING
!iv_url TYPE string
!iv_target_package TYPE devclass OPTIONAL
RETURNING
VALUE(rv_installed) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS list
RETURNING
VALUE(rt_list) TYPE zif_abapgit_definitions=>ty_repo_ref_tt
RAISING
zcx_abapgit_exception .
METHODS new_offline
IMPORTING
!iv_url TYPE string
!iv_package TYPE devclass
RETURNING
VALUE(ro_repo) TYPE REF TO zcl_abapgit_repo_offline
RAISING
zcx_abapgit_exception .
METHODS new_online
IMPORTING
!iv_url TYPE string
!iv_branch_name TYPE string
!iv_package TYPE devclass
RETURNING
VALUE(ro_repo) TYPE REF TO zcl_abapgit_repo_online
RAISING
zcx_abapgit_exception .
METHODS purge
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
is_checks TYPE zif_abapgit_definitions=>ty_delete_checks
RAISING
zcx_abapgit_exception .
METHODS switch_repo_type
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_value
!iv_offline TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS validate_package
IMPORTING
!iv_package TYPE devclass
RAISING
zcx_abapgit_exception .
ENDINTERFACE.
INTERFACE zif_abapgit_sap_package.
TYPES: ty_devclass_tt TYPE STANDARD TABLE OF devclass WITH DEFAULT KEY.
METHODS:
create
IMPORTING is_package TYPE scompkdtln
RAISING zcx_abapgit_exception,
create_local
RAISING zcx_abapgit_exception,
list_subpackages
RETURNING VALUE(rt_list) TYPE ty_devclass_tt,
list_superpackages
RETURNING VALUE(rt_list) TYPE ty_devclass_tt,
read_parent
RETURNING VALUE(rv_parentcl) TYPE tdevc-parentcl,
create_child
IMPORTING iv_child TYPE devclass
RAISING zcx_abapgit_exception,
exists
RETURNING VALUE(rv_bool) TYPE abap_bool,
are_changes_recorded_in_tr_req
RETURNING VALUE(rv_are_changes_rec_in_tr_req) TYPE abap_bool
RAISING zcx_abapgit_exception,
get_transport_type
RETURNING VALUE(rv_transport_type) TYPE zif_abapgit_definitions=>ty_transport_type
RAISING zcx_abapgit_exception.
ENDINTERFACE.
INTERFACE zif_abapgit_tadir
.
METHODS get_object_package
IMPORTING
!iv_pgmid TYPE tadir-pgmid DEFAULT 'R3TR'
!iv_object TYPE tadir-object
!iv_obj_name TYPE tadir-obj_name
RETURNING
VALUE(rv_devclass) TYPE tadir-devclass
RAISING
zcx_abapgit_exception .
METHODS read
IMPORTING
!iv_package TYPE tadir-devclass
!iv_ignore_subpackages TYPE abap_bool DEFAULT abap_false
!iv_only_local_objects TYPE abap_bool DEFAULT abap_false
!io_dot TYPE REF TO zcl_abapgit_dot_abapgit OPTIONAL
!io_log TYPE REF TO zcl_abapgit_log OPTIONAL
RETURNING
VALUE(rt_tadir) TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
METHODS read_single
IMPORTING
!iv_pgmid TYPE tadir-pgmid DEFAULT 'R3TR'
!iv_object TYPE tadir-object
!iv_obj_name TYPE tadir-obj_name
RETURNING
VALUE(rs_tadir) TYPE zif_abapgit_definitions=>ty_tadir
RAISING
zcx_abapgit_exception .
ENDINTERFACE.
INTERFACE zif_abapgit_version
.
CONSTANTS gc_xml_version TYPE string VALUE 'v1.0.0' ##NO_TEXT.
CONSTANTS gc_abap_version TYPE string VALUE '1.74.1' ##NO_TEXT.
ENDINTERFACE.
CLASS zcl_abapgit_background DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: BEGIN OF ty_methods,
class TYPE seoclsname,
description TYPE string,
END OF ty_methods.
TYPES: ty_methods_tt TYPE SORTED TABLE OF ty_methods WITH UNIQUE KEY class.
CLASS-METHODS run
RAISING
zcx_abapgit_exception .
CLASS-METHODS list_methods
RETURNING VALUE(rt_methods) TYPE ty_methods_tt.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_background_pull DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_background .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_background_push_au DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_background .
PROTECTED SECTION.
DATA mo_log TYPE REF TO zcl_abapgit_log .
METHODS build_comment
IMPORTING
!is_files TYPE zif_abapgit_definitions=>ty_stage_files
RETURNING
VALUE(rv_comment) TYPE string .
METHODS push_auto
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
RAISING
zcx_abapgit_exception .
METHODS determine_user_details
IMPORTING
!iv_changed_by TYPE xubname
RETURNING
VALUE(rs_user) TYPE zif_abapgit_definitions=>ty_git_user .
METHODS push_deletions
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
!is_files TYPE zif_abapgit_definitions=>ty_stage_files
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_background_push_fi DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_background .
PROTECTED SECTION.
CONSTANTS:
BEGIN OF c_settings,
name TYPE string VALUE 'NAME',
email TYPE string VALUE 'EMAIL',
END OF c_settings .
DATA mo_log TYPE REF TO zcl_abapgit_log .
METHODS build_comment
IMPORTING
!is_files TYPE zif_abapgit_definitions=>ty_stage_files
RETURNING
VALUE(rv_comment) TYPE string .
METHODS push_fixed
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
!iv_name TYPE string
!iv_email TYPE string
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_git_branch_list DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!iv_data TYPE string
RAISING
zcx_abapgit_exception .
METHODS find_by_name
IMPORTING
!iv_branch_name TYPE clike
RETURNING
VALUE(rs_branch) TYPE zif_abapgit_definitions=>ty_git_branch
RAISING
zcx_abapgit_exception .
METHODS get_head " For potential future use
RETURNING
VALUE(rs_branch) TYPE zif_abapgit_definitions=>ty_git_branch
RAISING
zcx_abapgit_exception .
METHODS get_head_symref
RETURNING
VALUE(rv_head_symref) TYPE string .
METHODS get_branches_only
RETURNING
VALUE(rt_branches) TYPE zif_abapgit_definitions=>ty_git_branch_list_tt
RAISING
zcx_abapgit_exception .
METHODS get_tags_only " For potential future use
RETURNING
VALUE(rt_tags) TYPE zif_abapgit_definitions=>ty_git_branch_list_tt
RAISING
zcx_abapgit_exception.
CLASS-METHODS is_ignored
IMPORTING
!iv_branch_name TYPE clike
RETURNING
VALUE(rv_ignore) TYPE abap_bool .
CLASS-METHODS get_display_name
IMPORTING
!iv_branch_name TYPE clike
RETURNING
VALUE(rv_display_name) TYPE string .
CLASS-METHODS get_type
IMPORTING
!iv_branch_name TYPE clike
it_result TYPE stringtab OPTIONAL
iv_current_row_index TYPE sytabix OPTIONAL
RETURNING
VALUE(rv_type) TYPE zif_abapgit_definitions=>ty_git_branch_type .
CLASS-METHODS complete_heads_branch_name
IMPORTING
!iv_branch_name TYPE clike
RETURNING
VALUE(rv_name) TYPE string .
CLASS-METHODS normalize_branch_name
IMPORTING
!iv_branch_name TYPE clike
RETURNING
VALUE(rv_name) TYPE string .
PRIVATE SECTION.
DATA mt_branches TYPE zif_abapgit_definitions=>ty_git_branch_list_tt .
DATA mv_head_symref TYPE string .
METHODS find_tag_by_name
IMPORTING
iv_branch_name TYPE string
RETURNING
VALUE(rs_branch) TYPE zif_abapgit_definitions=>ty_git_branch
RAISING
zcx_abapgit_exception.
CLASS-METHODS parse_branch_list
IMPORTING
!iv_data TYPE string
EXPORTING
!et_list TYPE zif_abapgit_definitions=>ty_git_branch_list_tt
!ev_head_symref TYPE string
RAISING
zcx_abapgit_exception .
CLASS-METHODS parse_head_params
IMPORTING
!iv_data TYPE string
RETURNING
VALUE(rv_head_symref) TYPE string .
ENDCLASS.
CLASS zcl_abapgit_git_pack DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
BEGIN OF ty_node,
chmod TYPE zif_abapgit_definitions=>ty_chmod,
name TYPE string,
sha1 TYPE zif_abapgit_definitions=>ty_sha1,
END OF ty_node .
TYPES:
ty_nodes_tt TYPE STANDARD TABLE OF ty_node WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_commit,
tree TYPE zif_abapgit_definitions=>ty_sha1,
parent TYPE zif_abapgit_definitions=>ty_sha1,
parent2 TYPE zif_abapgit_definitions=>ty_sha1,
author TYPE string,
committer TYPE string,
body TYPE string,
END OF ty_commit .
TYPES:
BEGIN OF ty_tag,
object TYPE string,
type TYPE string,
tag TYPE string,
tagger_name TYPE string,
tagger_email TYPE string,
message TYPE string,
body TYPE string,
END OF ty_tag .
CLASS-METHODS decode
IMPORTING
!iv_data TYPE xstring
RETURNING
VALUE(rt_objects) TYPE zif_abapgit_definitions=>ty_objects_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS decode_tree
IMPORTING
!iv_data TYPE xstring
RETURNING
VALUE(rt_nodes) TYPE ty_nodes_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS decode_commit
IMPORTING
!iv_data TYPE xstring
RETURNING
VALUE(rs_commit) TYPE ty_commit
RAISING
zcx_abapgit_exception .
CLASS-METHODS decode_tag
IMPORTING
!iv_data TYPE xstring
RETURNING
VALUE(rs_tag) TYPE ty_tag
RAISING
zcx_abapgit_exception .
CLASS-METHODS encode
IMPORTING
!it_objects TYPE zif_abapgit_definitions=>ty_objects_tt
RETURNING
VALUE(rv_data) TYPE xstring
RAISING
zcx_abapgit_exception .
CLASS-METHODS encode_tree
IMPORTING
!it_nodes TYPE ty_nodes_tt
RETURNING
VALUE(rv_data) TYPE xstring .
CLASS-METHODS encode_commit
IMPORTING
!is_commit TYPE ty_commit
RETURNING
VALUE(rv_data) TYPE xstring .
CLASS-METHODS encode_tag
IMPORTING
!is_tag TYPE zcl_abapgit_git_pack=>ty_tag
RETURNING
VALUE(rv_data) TYPE xstring
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
CONSTANTS:
c_pack_start TYPE x LENGTH 4 VALUE '5041434B' ##NO_TEXT.
CONSTANTS:
c_zlib TYPE x LENGTH 2 VALUE '789C' ##NO_TEXT.
CONSTANTS:
c_zlib_hmm TYPE x LENGTH 2 VALUE '7801' ##NO_TEXT.
CONSTANTS: " PACK
c_version TYPE x LENGTH 4 VALUE '00000002' ##NO_TEXT.
CLASS-METHODS decode_deltas
CHANGING
!ct_objects TYPE zif_abapgit_definitions=>ty_objects_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS delta
IMPORTING
!is_object TYPE zif_abapgit_definitions=>ty_object
CHANGING
!ct_objects TYPE zif_abapgit_definitions=>ty_objects_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS delta_header
EXPORTING
!ev_header TYPE i
CHANGING
!cv_delta TYPE xstring .
CLASS-METHODS sort_tree
IMPORTING
!it_nodes TYPE ty_nodes_tt
RETURNING
VALUE(rt_nodes) TYPE ty_nodes_tt .
CLASS-METHODS get_type
IMPORTING
!iv_x TYPE x
RETURNING
VALUE(rv_type) TYPE zif_abapgit_definitions=>ty_type
RAISING
zcx_abapgit_exception .
CLASS-METHODS get_length
EXPORTING
!ev_length TYPE i
CHANGING
!cv_data TYPE xstring .
CLASS-METHODS type_and_length
IMPORTING
!iv_type TYPE zif_abapgit_definitions=>ty_type
!iv_length TYPE i
RETURNING
VALUE(rv_xstring) TYPE xstring
RAISING
zcx_abapgit_exception .
CLASS-METHODS zlib_decompress
CHANGING
!cv_data TYPE xstring
!cv_decompressed TYPE xstring
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_git_porcelain DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
BEGIN OF ty_pull_result,
files TYPE zif_abapgit_definitions=>ty_files_tt,
objects TYPE zif_abapgit_definitions=>ty_objects_tt,
branch TYPE zif_abapgit_definitions=>ty_sha1,
END OF ty_pull_result .
TYPES:
BEGIN OF ty_push_result,
new_files TYPE zif_abapgit_definitions=>ty_files_tt,
branch TYPE zif_abapgit_definitions=>ty_sha1,
updated_files TYPE zif_abapgit_definitions=>ty_file_signatures_tt,
new_objects TYPE zif_abapgit_definitions=>ty_objects_tt,
END OF ty_push_result .
CLASS-METHODS pull
IMPORTING
!iv_url TYPE string
!iv_branch_name TYPE string
RETURNING
VALUE(rs_result) TYPE ty_pull_result
RAISING
zcx_abapgit_exception .
CLASS-METHODS push
IMPORTING
!is_comment TYPE zif_abapgit_definitions=>ty_comment
!io_stage TYPE REF TO zcl_abapgit_stage
!it_old_objects TYPE zif_abapgit_definitions=>ty_objects_tt
!iv_parent TYPE zif_abapgit_definitions=>ty_sha1
!iv_url TYPE string
!iv_branch_name TYPE string
RETURNING
VALUE(rs_result) TYPE ty_push_result
RAISING
zcx_abapgit_exception .
CLASS-METHODS create_branch
IMPORTING
!iv_url TYPE string
!iv_name TYPE string
!iv_from TYPE zif_abapgit_definitions=>ty_sha1
RAISING
zcx_abapgit_exception .
CLASS-METHODS create_tag
IMPORTING
!iv_url TYPE string
!is_tag TYPE zif_abapgit_definitions=>ty_git_tag
RAISING
zcx_abapgit_exception .
CLASS-METHODS delete_branch
IMPORTING
!iv_url TYPE string
!is_branch TYPE zif_abapgit_definitions=>ty_git_branch
RAISING
zcx_abapgit_exception .
CLASS-METHODS delete_tag
IMPORTING
!iv_url TYPE string
!is_tag TYPE zif_abapgit_definitions=>ty_git_tag
RAISING
zcx_abapgit_exception .
CLASS-METHODS full_tree
IMPORTING
!it_objects TYPE zif_abapgit_definitions=>ty_objects_tt
!iv_branch TYPE zif_abapgit_definitions=>ty_sha1
RETURNING
VALUE(rt_expanded) TYPE zif_abapgit_definitions=>ty_expanded_tt
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
TYPES:
BEGIN OF ty_tree,
path TYPE string,
data TYPE xstring,
sha1 TYPE zif_abapgit_definitions=>ty_sha1,
END OF ty_tree .
TYPES:
ty_trees_tt TYPE STANDARD TABLE OF ty_tree WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_folder,
path TYPE string,
count TYPE i,
sha1 TYPE zif_abapgit_definitions=>ty_sha1,
END OF ty_folder .
TYPES:
ty_folders_tt TYPE STANDARD TABLE OF ty_folder WITH DEFAULT KEY .
CONSTANTS c_zero TYPE zif_abapgit_definitions=>ty_sha1 VALUE '0000000000000000000000000000000000000000' ##NO_TEXT.
CLASS-METHODS build_trees
IMPORTING
!it_expanded TYPE zif_abapgit_definitions=>ty_expanded_tt
RETURNING
VALUE(rt_trees) TYPE ty_trees_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS find_folders
IMPORTING
!it_expanded TYPE zif_abapgit_definitions=>ty_expanded_tt
RETURNING
VALUE(rt_folders) TYPE ty_folders_tt .
CLASS-METHODS walk
IMPORTING
!it_objects TYPE zif_abapgit_definitions=>ty_objects_tt
!iv_sha1 TYPE zif_abapgit_definitions=>ty_sha1
!iv_path TYPE string
CHANGING
!ct_files TYPE zif_abapgit_definitions=>ty_files_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS walk_tree
IMPORTING
!it_objects TYPE zif_abapgit_definitions=>ty_objects_tt
!iv_tree TYPE zif_abapgit_definitions=>ty_sha1
!iv_base TYPE string
RETURNING
VALUE(rt_expanded) TYPE zif_abapgit_definitions=>ty_expanded_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS receive_pack_push
IMPORTING
!is_comment TYPE zif_abapgit_definitions=>ty_comment
!it_trees TYPE ty_trees_tt
!it_blobs TYPE zif_abapgit_definitions=>ty_files_tt
!iv_parent TYPE zif_abapgit_definitions=>ty_sha1
!iv_parent2 TYPE zif_abapgit_definitions=>ty_sha1 OPTIONAL
!iv_url TYPE string
!iv_branch_name TYPE string
EXPORTING
!ev_new_commit TYPE zif_abapgit_definitions=>ty_sha1
!et_new_objects TYPE zif_abapgit_definitions=>ty_objects_tt
!ev_new_tree TYPE zif_abapgit_definitions=>ty_sha1
RAISING
zcx_abapgit_exception .
CLASS-METHODS receive_pack_create_tag
IMPORTING
!is_tag TYPE zif_abapgit_definitions=>ty_git_tag
!iv_url TYPE string
RAISING
zcx_abapgit_exception .
CLASS-METHODS create_annotated_tag
IMPORTING
!is_tag TYPE zif_abapgit_definitions=>ty_git_tag
!iv_url TYPE string
RAISING
zcx_abapgit_exception .
CLASS-METHODS create_lightweight_tag
IMPORTING
!is_tag TYPE zif_abapgit_definitions=>ty_git_tag
!iv_url TYPE string
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_git_transport DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS upload_pack
IMPORTING iv_url TYPE string
iv_branch_name TYPE string
iv_deepen TYPE abap_bool DEFAULT abap_true
it_branches TYPE zif_abapgit_definitions=>ty_git_branch_list_tt OPTIONAL
EXPORTING et_objects TYPE zif_abapgit_definitions=>ty_objects_tt
ev_branch TYPE zif_abapgit_definitions=>ty_sha1
eo_branch_list TYPE REF TO zcl_abapgit_git_branch_list
RAISING zcx_abapgit_exception.
CLASS-METHODS receive_pack
IMPORTING iv_url TYPE string
iv_old TYPE zif_abapgit_definitions=>ty_sha1
iv_new TYPE zif_abapgit_definitions=>ty_sha1
iv_branch_name TYPE string
iv_pack TYPE xstring
RAISING zcx_abapgit_exception.
CLASS-METHODS branches
IMPORTING iv_url TYPE string
RETURNING VALUE(ro_branch_list) TYPE REF TO zcl_abapgit_git_branch_list
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_service,
receive TYPE string VALUE 'receive', "#EC NOTEXT
upload TYPE string VALUE 'upload', "#EC NOTEXT
END OF c_service.
CLASS-METHODS branch_list
IMPORTING iv_url TYPE string
iv_service TYPE string
EXPORTING eo_client TYPE REF TO zcl_abapgit_http_client
eo_branch_list TYPE REF TO zcl_abapgit_git_branch_list
RAISING zcx_abapgit_exception.
CLASS-METHODS find_branch
IMPORTING iv_url TYPE string
iv_service TYPE string
iv_branch_name TYPE string
EXPORTING eo_client TYPE REF TO zcl_abapgit_http_client
ev_branch TYPE zif_abapgit_definitions=>ty_sha1
eo_branch_list TYPE REF TO zcl_abapgit_git_branch_list
RAISING zcx_abapgit_exception.
CLASS-METHODS parse
EXPORTING ev_pack TYPE xstring
CHANGING cv_data TYPE xstring
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_git_utils DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS get_null
RETURNING VALUE(rv_c) TYPE char1.
CLASS-METHODS pkt_string
IMPORTING iv_string TYPE string
RETURNING VALUE(rv_pkt) TYPE string
RAISING zcx_abapgit_exception.
CLASS-METHODS length_utf8_hex
IMPORTING iv_data TYPE xstring
RETURNING VALUE(rv_len) TYPE i
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_tag DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS:
add_tag_prefix
IMPORTING
iv_text TYPE csequence
RETURNING
VALUE(rv_text) TYPE string,
remove_tag_prefix
IMPORTING
iv_text TYPE string
RETURNING
VALUE(rv_text) TYPE string.
ENDCLASS.
"! Default <em>LIF_2FA-AUTHENTICATOR</em> implememtation
CLASS zcl_abapgit_2fa_auth_base DEFINITION
ABSTRACT
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES:
zif_abapgit_2fa_authenticator.
ALIASES:
authenticate FOR zif_abapgit_2fa_authenticator~authenticate,
supports_url FOR zif_abapgit_2fa_authenticator~supports_url,
is_2fa_required FOR zif_abapgit_2fa_authenticator~is_2fa_required,
delete_access_tokens FOR zif_abapgit_2fa_authenticator~delete_access_tokens,
begin FOR zif_abapgit_2fa_authenticator~begin,
end FOR zif_abapgit_2fa_authenticator~end.
METHODS:
"! @parameter iv_supported_url_regex | Regular expression to check if a repository url is
"! supported, used for default implementation of
"! <em>SUPPORTS_URL</em>
constructor IMPORTING iv_supported_url_regex TYPE clike.
PROTECTED SECTION.
CLASS-METHODS:
"! Helper method to raise class based exception after traditional exception was raised
"! <p>
"! <em>sy-msg...</em> must be set right before calling!
"! </p>
raise_comm_error_from_sy RAISING zcx_abapgit_2fa_comm_error.
METHODS:
"! @parameter rv_running | Internal session is currently active
is_session_running RETURNING VALUE(rv_running) TYPE abap_bool,
"! Returns HTTP client configured with proxy (where required) for the given URL
get_http_client_for_url
IMPORTING iv_url TYPE string
RETURNING VALUE(ri_client) TYPE REF TO if_http_client
RAISING zcx_abapgit_2fa_comm_error.
PRIVATE SECTION.
DATA:
mo_url_regex TYPE REF TO cl_abap_regex,
mv_session_running TYPE abap_bool.
ENDCLASS.
"! Static registry class to find <em>LIF_2FA_AUTHENTICATOR</em> instances
CLASS zcl_abapgit_2fa_auth_registry DEFINITION
FINAL
CREATE PRIVATE .
PUBLIC SECTION.
CLASS-METHODS:
class_constructor,
"! Retrieve an authenticator instance by url
"! @parameter iv_url | Url of the repository / service
"! @parameter ro_authenticator | Found authenticator instance
"! @raising lcx_2fa_unsupported | No authenticator found that supports the service
get_authenticator_for_url IMPORTING iv_url TYPE string
RETURNING VALUE(ri_authenticator) TYPE REF TO zif_abapgit_2fa_authenticator
RAISING zcx_abapgit_2fa_unsupported,
"! Check if there is a two factor authenticator available for the url
"! @parameter iv_url | Url of the repository / service
"! @parameter rv_supported | 2FA is supported
is_url_supported IMPORTING iv_url TYPE string
RETURNING VALUE(rv_supported) TYPE abap_bool,
"! Offer to use two factor authentication if supported and required
"! <p>
"! This uses GUI functionality to display a popup to request the user to enter a two factor
"! token. Also an dummy authentication request might be used to find out if two factor
"! authentication is required for the account.
"! </p>
"! @parameter iv_url | Url of the repository / service
"! @parameter cv_username | Username
"! @parameter cv_password | Password, will be replaced by an access token if two factor
"! authentication succeeds
"! @raising zcx_abapgit_exception | Error in two factor authentication
use_2fa_if_required IMPORTING iv_url TYPE string
CHANGING cv_username TYPE string
cv_password TYPE string
RAISING zcx_abapgit_exception.
CLASS-DATA:
"! All authenticators managed by the registry
gt_registered_authenticators TYPE HASHED TABLE OF REF TO zif_abapgit_2fa_authenticator
WITH UNIQUE KEY table_line READ-ONLY.
PRIVATE SECTION.
CLASS-METHODS:
popup_token
RETURNING VALUE(rv_token) TYPE string
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_2fa_github_auth DEFINITION
INHERITING FROM zcl_abapgit_2fa_auth_base
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!iv_override TYPE string OPTIONAL .
METHODS zif_abapgit_2fa_authenticator~authenticate
REDEFINITION .
METHODS zif_abapgit_2fa_authenticator~delete_access_tokens
REDEFINITION .
METHODS zif_abapgit_2fa_authenticator~end
REDEFINITION .
METHODS zif_abapgit_2fa_authenticator~is_2fa_required
REDEFINITION .
PROTECTED SECTION.
DATA mv_github_api_url TYPE string VALUE `https://api.github.com/` ##NO_TEXT.
PRIVATE SECTION.
CONSTANTS c_otp_header_name TYPE string VALUE `X-Github-OTP` ##NO_TEXT.
CONSTANTS c_restendpoint_authorizations TYPE string VALUE `/authorizations` ##NO_TEXT.
DATA mi_authenticated_session TYPE REF TO if_http_client .
CLASS-METHODS set_new_token_request
IMPORTING
!ii_request TYPE REF TO if_http_request .
CLASS-METHODS get_token_from_response
IMPORTING
!ii_response TYPE REF TO if_http_response
RETURNING
VALUE(rv_token) TYPE string .
CLASS-METHODS set_list_token_request
IMPORTING
!ii_request TYPE REF TO if_http_request .
CLASS-METHODS get_tobedel_tokens_from_resp
IMPORTING
!ii_response TYPE REF TO if_http_response
RETURNING
VALUE(rt_ids) TYPE stringtab .
CLASS-METHODS set_del_token_request
IMPORTING
!ii_request TYPE REF TO if_http_request
!iv_token_id TYPE string .
METHODS get_authenticated_client
IMPORTING
!iv_username TYPE string
!iv_password TYPE string
!iv_2fa_token TYPE string
RETURNING
VALUE(ri_client) TYPE REF TO if_http_client
RAISING
zcx_abapgit_2fa_auth_failed
zcx_abapgit_2fa_comm_error .
ENDCLASS.
CLASS zcl_abapgit_http DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CONSTANTS: BEGIN OF c_scheme,
digest TYPE string VALUE 'Digest',
END OF c_scheme.
CLASS-METHODS:
get_agent
RETURNING VALUE(rv_agent) TYPE string,
create_by_url
IMPORTING iv_url TYPE string
iv_service TYPE string
RETURNING VALUE(ro_client) TYPE REF TO zcl_abapgit_http_client
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CLASS-METHODS:
check_auth_requested
IMPORTING ii_client TYPE REF TO if_http_client
RETURNING VALUE(rv_auth_requested) TYPE abap_bool
RAISING zcx_abapgit_exception,
is_local_system
IMPORTING iv_url TYPE string
RETURNING VALUE(rv_bool) TYPE abap_bool,
acquire_login_details
IMPORTING ii_client TYPE REF TO if_http_client
io_client TYPE REF TO zcl_abapgit_http_client
iv_url TYPE string
RETURNING VALUE(rv_scheme) TYPE string
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_http_digest DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!ii_client TYPE REF TO if_http_client
!iv_username TYPE string
!iv_password TYPE string
RAISING
zcx_abapgit_exception.
METHODS run
IMPORTING
!ii_client TYPE REF TO if_http_client
RAISING
zcx_abapgit_exception.
PRIVATE SECTION.
DATA: mv_ha1 TYPE string,
mv_username TYPE string,
mv_realm TYPE string,
mv_qop TYPE string,
mv_nonce TYPE string.
CLASS-DATA: gv_nc TYPE n LENGTH 8.
CLASS-METHODS:
md5
IMPORTING
iv_data TYPE string
RETURNING
VALUE(rv_hash) TYPE string
RAISING zcx_abapgit_exception.
METHODS:
hash
IMPORTING
iv_qop TYPE string
iv_nonce TYPE string
iv_uri TYPE string
iv_method TYPE string
iv_cnonse TYPE string
RETURNING
VALUE(rv_response) TYPE string
RAISING zcx_abapgit_exception,
parse
IMPORTING
ii_client TYPE REF TO if_http_client.
ENDCLASS.
CLASS zcl_abapgit_proxy_auth DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS:
run
IMPORTING ii_client TYPE REF TO if_http_client
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CLASS-DATA: gv_username TYPE string,
gv_password TYPE string.
CLASS-METHODS: enter RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_proxy_config DEFINITION FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
constructor,
get_proxy_url
IMPORTING
iv_repo_url TYPE csequence OPTIONAL
RETURNING
VALUE(rv_proxy_url) TYPE string,
get_proxy_port
IMPORTING
iv_repo_url TYPE csequence OPTIONAL
RETURNING
VALUE(rv_port) TYPE string,
get_proxy_authentication
IMPORTING
iv_repo_url TYPE csequence OPTIONAL
RETURNING
VALUE(rv_auth) TYPE abap_bool.
PRIVATE SECTION.
DATA: mo_settings TYPE REF TO zcl_abapgit_settings,
mi_exit TYPE REF TO zif_abapgit_exit.
ENDCLASS.
CLASS zcl_abapgit_ecatt_config_downl DEFINITION
INHERITING FROM cl_apl_ecatt_config_download
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
download REDEFINITION,
get_xml_stream
RETURNING
VALUE(rv_xml_stream) TYPE xstring,
get_xml_stream_size
RETURNING
VALUE(rv_xml_stream_size) TYPE int4.
PROTECTED SECTION.
METHODS:
download_data REDEFINITION.
PRIVATE SECTION.
DATA:
mv_xml_stream TYPE xstring,
mv_xml_stream_size TYPE int4.
ENDCLASS.
CLASS zcl_abapgit_ecatt_config_upl DEFINITION
INHERITING FROM cl_apl_ecatt_config_upload
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
z_set_stream_for_upload
IMPORTING
iv_xml TYPE xstring.
PROTECTED SECTION.
METHODS:
upload_data_from_stream REDEFINITION.
PRIVATE SECTION.
DATA: mv_external_xml TYPE xstring.
ENDCLASS.
CLASS zcl_abapgit_ecatt_data_downl DEFINITION
INHERITING FROM cl_apl_ecatt_data_download
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
download REDEFINITION,
set_generate_xml_no_download
IMPORTING
iv_generate_xml_no_download TYPE abap_bool,
get_xml_stream
RETURNING
VALUE(rv_xml_stream) TYPE xstring,
get_xml_stream_size
RETURNING
VALUE(rv_xml_stream_size) TYPE int4.
PROTECTED SECTION.
METHODS:
download_data REDEFINITION.
PRIVATE SECTION.
DATA:
mv_generate_xml_no_download TYPE abap_bool,
mv_xml_stream TYPE xstring,
mv_xml_stream_size TYPE int4.
ENDCLASS.
CLASS zcl_abapgit_ecatt_data_upload DEFINITION
INHERITING FROM cl_apl_ecatt_data_upload
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
z_set_stream_for_upload
IMPORTING
iv_xml TYPE xstring.
PROTECTED SECTION.
METHODS:
upload_data_from_stream REDEFINITION.
PRIVATE SECTION.
DATA: mv_external_xml TYPE xstring.
ENDCLASS.
CLASS zcl_abapgit_ecatt_helper DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS:
build_xml_of_object
IMPORTING
im_object_name TYPE etobj_name
im_object_version TYPE etobj_ver
im_object_type TYPE etobj_type
io_download TYPE REF TO cl_apl_ecatt_download
EXPORTING
ex_xml_stream TYPE xstring
ex_xml_stream_size TYPE int4
RAISING
zcx_abapgit_exception,
download_data
IMPORTING
ii_template_over_all TYPE REF TO if_ixml_document
EXPORTING
ev_xml_stream TYPE xstring
ev_xml_stream_size TYPE i,
upload_data_from_stream
IMPORTING
iv_xml_stream TYPE xstring
RETURNING
VALUE(ri_template_over_all) TYPE REF TO if_ixml_document
RAISING
cx_ecatt_apl_xml.
PRIVATE SECTION.
CONSTANTS:
co_xml TYPE int4 VALUE 1. " downport of if_apl_ecatt_xml=>co_xml
ENDCLASS.
CLASS zcl_abapgit_ecatt_script_downl DEFINITION
INHERITING FROM cl_apl_ecatt_script_download
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
download REDEFINITION,
get_xml_stream
RETURNING
VALUE(rv_xml_stream) TYPE xstring,
get_xml_stream_size
RETURNING
VALUE(rv_xml_stream_size) TYPE int4.
PROTECTED SECTION.
METHODS:
download_data REDEFINITION.
PRIVATE SECTION.
DATA:
mv_xml_stream TYPE xstring,
mv_xml_stream_size TYPE int4,
mi_script_node TYPE REF TO if_ixml_element.
METHODS:
set_script_to_template
RAISING
cx_ecatt_apl_util,
set_control_data_for_tcd
IMPORTING
is_param TYPE etpar_gui
io_params TYPE REF TO cl_apl_ecatt_params
RAISING
cx_ecatt_apl,
escape_control_data
IMPORTING
ii_element TYPE REF TO if_ixml_element
iv_tabname TYPE string
iv_node TYPE string
RAISING
cx_ecatt_apl_util,
set_blob_to_template
RAISING
cx_ecatt_apl_util,
set_artmp_to_template
RAISING
cx_ecatt_apl_util.
ENDCLASS.
CLASS zcl_abapgit_ecatt_script_upl DEFINITION
INHERITING FROM cl_apl_ecatt_script_upload
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
z_set_stream_for_upload
IMPORTING
iv_xml TYPE xstring.
PROTECTED SECTION.
METHODS:
upload_data_from_stream REDEFINITION.
PRIVATE SECTION.
DATA: mv_external_xml TYPE xstring.
ENDCLASS.
CLASS zcl_abapgit_ecatt_sp_download DEFINITION
INHERITING FROM cl_apl_ecatt_download
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
download REDEFINITION,
get_xml_stream
RETURNING
VALUE(rv_xml_stream) TYPE xstring,
get_xml_stream_size
RETURNING
VALUE(rv_xml_stream_size) TYPE int4.
PROTECTED SECTION.
METHODS:
download_data REDEFINITION.
PRIVATE SECTION.
DATA:
mv_xml_stream TYPE xstring,
mv_xml_stream_size TYPE int4.
METHODS:
set_sp_data_to_template.
ENDCLASS.
CLASS zcl_abapgit_ecatt_sp_upload DEFINITION
INHERITING FROM cl_apl_ecatt_upload
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
z_set_stream_for_upload
IMPORTING
iv_xml TYPE xstring,
upload
REDEFINITION.
PROTECTED SECTION.
METHODS:
upload_data_from_stream REDEFINITION,
get_ecatt_sp
RAISING
cx_ecatt_apl .
PRIVATE SECTION.
DATA: mv_external_xml TYPE xstring.
ENDCLASS.
CLASS zcl_abapgit_ecatt_system_downl DEFINITION
INHERITING FROM cl_apl_ecatt_systems_download
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
download REDEFINITION,
get_xml_stream
RETURNING
VALUE(rv_xml_stream) TYPE xstring,
get_xml_stream_size
RETURNING
VALUE(rv_xml_stream_size) TYPE int4.
PROTECTED SECTION.
METHODS:
download_data REDEFINITION.
PRIVATE SECTION.
DATA:
mv_xml_stream TYPE xstring,
mv_xml_stream_size TYPE int4.
METHODS:
set_systems_data_to_template.
ENDCLASS.
CLASS zcl_abapgit_ecatt_system_upl DEFINITION
INHERITING FROM cl_apl_ecatt_systems_upload
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
z_set_stream_for_upload
IMPORTING
iv_xml TYPE xstring.
PROTECTED SECTION.
METHODS:
upload_data_from_stream REDEFINITION.
PRIVATE SECTION.
DATA: mv_external_xml TYPE xstring.
ENDCLASS.
CLASS zcl_abapgit_ecatt_val_obj_down DEFINITION
INHERITING FROM cl_apl_ecatt_download
CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
download REDEFINITION,
get_xml_stream
RETURNING
VALUE(rv_xml_stream) TYPE xstring,
get_xml_stream_size
RETURNING
VALUE(rv_xml_stream_size) TYPE int4.
PROTECTED SECTION.
DATA:
li_objects_node TYPE REF TO if_ixml_element.
METHODS:
download_data REDEFINITION.
PRIVATE SECTION.
DATA:
mv_xml_stream TYPE xstring,
mv_xml_stream_size TYPE int4.
METHODS:
set_ecatt_impl_detail,
set_ecatt_flags,
set_business_msgs.
ENDCLASS.
CLASS zcl_abapgit_ecatt_val_obj_upl DEFINITION
INHERITING FROM cl_apl_ecatt_upload
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
z_set_stream_for_upload
IMPORTING
iv_xml TYPE xstring,
upload REDEFINITION.
PROTECTED SECTION.
METHODS:
upload_data_from_stream REDEFINITION,
get_business_msgs_from_dom
RAISING
cx_ecatt_apl,
get_impl_detail_from_dom
RAISING
cx_ecatt_apl,
get_vo_flags_from_dom
RAISING
cx_ecatt_apl.
PRIVATE SECTION.
DATA:
mv_external_xml TYPE xstring.
ENDCLASS.
CLASS zcl_abapgit_comparison_null DEFINITION FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES zif_abapgit_comparison_result .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_object_enho_badi DEFINITION.
PUBLIC SECTION.
METHODS: constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
io_files TYPE REF TO zcl_abapgit_objects_files.
INTERFACES: zif_abapgit_object_enho.
PRIVATE SECTION.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item.
ENDCLASS.
CLASS zcl_abapgit_object_enho_class DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
io_files TYPE REF TO zcl_abapgit_objects_files.
INTERFACES: zif_abapgit_object_enho.
PRIVATE SECTION.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item.
DATA: mo_files TYPE REF TO zcl_abapgit_objects_files.
ENDCLASS.
CLASS zcl_abapgit_object_enho_clif DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
deserialize
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
io_clif TYPE REF TO cl_enh_tool_clif
RAISING zcx_abapgit_exception
cx_enh_root,
serialize
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
io_files TYPE REF TO zcl_abapgit_objects_files
io_clif TYPE REF TO cl_enh_tool_clif
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CLASS-METHODS: serialize_includes
IMPORTING io_files TYPE REF TO zcl_abapgit_objects_files
io_clif TYPE REF TO cl_enh_tool_clif
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_enho_fugr DEFINITION.
PUBLIC SECTION.
METHODS: constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
io_files TYPE REF TO zcl_abapgit_objects_files.
INTERFACES: zif_abapgit_object_enho.
PRIVATE SECTION.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item,
mo_files TYPE REF TO zcl_abapgit_objects_files.
ENDCLASS.
CLASS zcl_abapgit_object_enho_hook DEFINITION.
PUBLIC SECTION.
METHODS: constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
io_files TYPE REF TO zcl_abapgit_objects_files.
INTERFACES: zif_abapgit_object_enho.
PRIVATE SECTION.
TYPES: BEGIN OF ty_spaces,
full_name TYPE string.
TYPES: spaces TYPE STANDARD TABLE OF i WITH DEFAULT KEY,
END OF ty_spaces.
TYPES: ty_spaces_tt TYPE STANDARD TABLE OF ty_spaces WITH DEFAULT KEY.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item.
DATA: mo_files TYPE REF TO zcl_abapgit_objects_files.
METHODS hook_impl_deserialize
IMPORTING it_spaces TYPE ty_spaces_tt
CHANGING ct_impl TYPE enh_hook_impl_it
RAISING zcx_abapgit_exception.
METHODS hook_impl_serialize
EXPORTING et_spaces TYPE ty_spaces_tt
CHANGING ct_impl TYPE enh_hook_impl_it
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_enho_intf DEFINITION.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
io_files TYPE REF TO zcl_abapgit_objects_files.
INTERFACES: zif_abapgit_object_enho.
PRIVATE SECTION.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item,
mo_files TYPE REF TO zcl_abapgit_objects_files.
ENDCLASS.
CLASS zcl_abapgit_object_enho_wdyc DEFINITION.
PUBLIC SECTION.
METHODS: constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
io_files TYPE REF TO zcl_abapgit_objects_files.
INTERFACES: zif_abapgit_object_enho.
PRIVATE SECTION.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item.
ENDCLASS.
CLASS zcl_abapgit_object_enho_wdyn DEFINITION.
PUBLIC SECTION.
METHODS: constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
io_files TYPE REF TO zcl_abapgit_objects_files.
INTERFACES: zif_abapgit_object_enho.
PRIVATE SECTION.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item.
ENDCLASS.
CLASS zcl_abapgit_object_enhs_badi_d DEFINITION.
PUBLIC SECTION.
INTERFACES: zif_abapgit_object_enhs.
ENDCLASS.
CLASS zcl_abapgit_object_enhs_hook_d DEFINITION.
PUBLIC SECTION.
INTERFACES: zif_abapgit_object_enhs.
PRIVATE SECTION.
TYPES: BEGIN OF ty_hook_defifnition,
pgmid TYPE pgmid,
obj_name TYPE trobj_name,
obj_type TYPE trobjtype,
main_type TYPE trobjtype,
main_name TYPE eu_aname,
program TYPE progname,
def_hooks TYPE enh_hook_def_ext_it,
END OF ty_hook_defifnition.
ENDCLASS.
CLASS zcl_abapgit_object_tabl_dialog DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_message TYPE string.
INTERFACES: zif_abapgit_comparison_result.
PRIVATE SECTION.
DATA mv_message TYPE string.
DATA mv_halt TYPE string.
ENDCLASS.
CLASS zcl_abapgit_object_tabl_valid DEFINITION FINAL.
PUBLIC SECTION.
METHODS validate
IMPORTING
io_remote_version TYPE REF TO zcl_abapgit_xml_input
io_local_version TYPE REF TO zcl_abapgit_xml_input
RETURNING
VALUE(rv_message) TYPE string
RAISING
zcx_abapgit_exception.
PRIVATE SECTION.
TYPES:
tty_founds TYPE STANDARD TABLE OF rsfindlst
WITH NON-UNIQUE DEFAULT KEY,
tty_seu_obj TYPE STANDARD TABLE OF seu_obj
WITH NON-UNIQUE DEFAULT KEY.
METHODS:
get_where_used_recursive
IMPORTING
iv_object_name TYPE csequence
iv_depth TYPE i
iv_object_type TYPE euobj-id
it_scope TYPE tty_seu_obj
RETURNING
VALUE(rt_founds_all) TYPE tty_founds
RAISING
zcx_abapgit_exception,
is_structure_used_in_db_table
IMPORTING
iv_object_name TYPE dd02v-tabname
RETURNING
VALUE(rv_is_structure_used_in_db_tab) TYPE abap_bool
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_objects_activation DEFINITION CREATE PUBLIC.
PUBLIC SECTION.
CLASS-METHODS add
IMPORTING iv_type TYPE trobjtype
iv_name TYPE clike
iv_delete TYPE abap_bool DEFAULT abap_false
RAISING zcx_abapgit_exception.
CLASS-METHODS add_item
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_item
RAISING zcx_abapgit_exception.
CLASS-METHODS activate
IMPORTING iv_ddic TYPE abap_bool DEFAULT abap_false
RAISING zcx_abapgit_exception.
CLASS-METHODS clear.
PRIVATE SECTION.
CLASS-DATA:
gt_classes TYPE STANDARD TABLE OF seoclsname WITH DEFAULT KEY,
gt_objects TYPE TABLE OF dwinactiv.
CLASS-METHODS update_where_used .
CLASS-METHODS fix_class_methods
IMPORTING
!iv_obj_name TYPE trobj_name
CHANGING
!ct_objects TYPE dwinactiv_tab .
CLASS-METHODS use_new_activation_logic
RETURNING
VALUE(rv_use_new_activation_logic) TYPE abap_bool .
CLASS-METHODS activate_new
IMPORTING
!iv_ddic TYPE abap_bool DEFAULT abap_false
RAISING
zcx_abapgit_exception .
CLASS-METHODS activate_old
IMPORTING
!iv_ddic TYPE abap_bool DEFAULT abap_false
RAISING
zcx_abapgit_exception .
CLASS-METHODS activate_ddic
RAISING
zcx_abapgit_exception .
CLASS-METHODS show_activation_errors
IMPORTING
!iv_logname TYPE ddmass-logname
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_objects_files DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_item
iv_path TYPE string OPTIONAL,
add_string
IMPORTING iv_extra TYPE clike OPTIONAL
iv_ext TYPE string
iv_string TYPE string
RAISING zcx_abapgit_exception,
read_string
IMPORTING iv_extra TYPE clike OPTIONAL
iv_ext TYPE string
RETURNING VALUE(rv_string) TYPE string
RAISING zcx_abapgit_exception,
add_xml
IMPORTING iv_extra TYPE clike OPTIONAL
io_xml TYPE REF TO zcl_abapgit_xml_output
iv_normalize TYPE sap_bool DEFAULT abap_true
is_metadata TYPE zif_abapgit_definitions=>ty_metadata OPTIONAL
RAISING zcx_abapgit_exception,
add_xml_from_plugin
IMPORTING iv_extra TYPE clike OPTIONAL
io_xml TYPE REF TO object
iv_normalize TYPE sap_bool DEFAULT abap_true
RAISING zcx_abapgit_exception ##called,
read_xml
IMPORTING iv_extra TYPE clike OPTIONAL
RETURNING VALUE(ro_xml) TYPE REF TO zcl_abapgit_xml_input
RAISING zcx_abapgit_exception,
read_abap
IMPORTING iv_extra TYPE clike OPTIONAL
iv_error TYPE sap_bool DEFAULT abap_true
RETURNING VALUE(rt_abap) TYPE abaptxt255_tab
RAISING zcx_abapgit_exception,
add_abap
IMPORTING iv_extra TYPE clike OPTIONAL
it_abap TYPE STANDARD TABLE
RAISING zcx_abapgit_exception,
add
IMPORTING is_file TYPE zif_abapgit_definitions=>ty_file,
add_raw
IMPORTING iv_extra TYPE clike OPTIONAL
iv_ext TYPE string
iv_data TYPE xstring
RAISING zcx_abapgit_exception,
read_raw
IMPORTING iv_extra TYPE clike OPTIONAL
iv_ext TYPE string
RETURNING VALUE(rv_data) TYPE xstring
RAISING zcx_abapgit_exception,
get_files
RETURNING VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_files_tt,
set_files
IMPORTING it_files TYPE zif_abapgit_definitions=>ty_files_tt,
get_accessed_files
RETURNING VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_file_signatures_tt.
PRIVATE SECTION.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item,
mt_accessed_files TYPE zif_abapgit_definitions=>ty_file_signatures_tt,
mt_files TYPE zif_abapgit_definitions=>ty_files_tt,
mv_path TYPE string.
METHODS:
read_file
IMPORTING iv_filename TYPE string
iv_error TYPE abap_bool DEFAULT abap_true
EXPORTING ev_data TYPE xstring
RAISING zcx_abapgit_exception,
filename
IMPORTING iv_extra TYPE clike OPTIONAL
iv_ext TYPE string
RETURNING VALUE(rv_filename) TYPE string.
ENDCLASS.
CLASS zcl_abapgit_objects_generic DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
RAISING
zcx_abapgit_exception .
METHODS delete
RAISING
zcx_abapgit_exception .
METHODS deserialize
IMPORTING
!iv_package TYPE devclass
!io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING
zcx_abapgit_exception .
METHODS exists
RETURNING
VALUE(rv_bool) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS serialize
IMPORTING
!io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING
zcx_abapgit_exception .
PROTECTED SECTION.
TYPES:
BEGIN OF ty_s_objkey,
num TYPE numc3,
value TYPE char128,
END OF ty_s_objkey .
TYPES:
ty_t_objkey TYPE SORTED TABLE OF ty_s_objkey WITH UNIQUE KEY num .
DATA ms_object_header TYPE objh .
DATA:
mt_object_table TYPE STANDARD TABLE OF objsl WITH DEFAULT KEY .
DATA:
mt_object_method TYPE STANDARD TABLE OF objm WITH DEFAULT KEY .
DATA ms_item TYPE zif_abapgit_definitions=>ty_item .
METHODS after_import .
METHODS before_export .
METHODS corr_insert
IMPORTING
!iv_package TYPE devclass
RAISING
zcx_abapgit_exception .
METHODS deserialize_data
IMPORTING
!io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING
zcx_abapgit_exception .
METHODS distribute_name_to_components
IMPORTING
!it_key_component TYPE ddfields
CHANGING
!ct_objkey TYPE ty_t_objkey
!cs_objkey TYPE ty_s_objkey
!cv_non_value_pos TYPE numc3 .
METHODS get_key_fields
IMPORTING
!iv_table TYPE objsl-tobj_name
RETURNING
VALUE(rt_keys) TYPE ddfields
RAISING
zcx_abapgit_exception .
METHODS get_primary_table
RETURNING
VALUE(rv_table) TYPE objsl-tobj_name
RAISING
zcx_abapgit_exception .
METHODS get_where_clause
IMPORTING
!iv_tobj_name TYPE objsl-tobj_name
RETURNING
VALUE(rv_where) TYPE string
RAISING
zcx_abapgit_exception .
METHODS serialize_data
IMPORTING
!io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING
zcx_abapgit_exception .
METHODS split_value_to_keys
IMPORTING
!it_key_component TYPE ddfields
CHANGING
!ct_objkey TYPE ty_t_objkey
!cs_objkey TYPE ty_s_objkey
!cv_non_value_pos TYPE numc3 .
METHODS validate
IMPORTING
!io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_objects_super DEFINITION ABSTRACT.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
CLASS-METHODS:
jump_adt
IMPORTING i_obj_name TYPE zif_abapgit_definitions=>ty_item-obj_name
i_obj_type TYPE zif_abapgit_definitions=>ty_item-obj_type
RAISING zcx_abapgit_exception.
CONSTANTS: c_user_unknown TYPE xubname VALUE 'UNKNOWN'.
PROTECTED SECTION.
DATA: ms_item TYPE zif_abapgit_definitions=>ty_item,
mv_language TYPE spras.
METHODS:
check_timestamp
IMPORTING
iv_timestamp TYPE timestamp
iv_date TYPE datum
iv_time TYPE uzeit
RETURNING
VALUE(rv_changed) TYPE abap_bool,
get_metadata
RETURNING VALUE(rs_metadata) TYPE zif_abapgit_definitions=>ty_metadata,
corr_insert
IMPORTING iv_package TYPE devclass
RAISING zcx_abapgit_exception,
tadir_insert
IMPORTING iv_package TYPE devclass
RAISING zcx_abapgit_exception,
jump_se11
IMPORTING iv_radio TYPE string
iv_field TYPE string
RAISING zcx_abapgit_exception,
exists_a_lock_entry_for
IMPORTING iv_lock_object TYPE string
iv_argument TYPE seqg3-garg OPTIONAL
RETURNING VALUE(rv_exists_a_lock_entry) TYPE abap_bool
RAISING zcx_abapgit_exception,
set_default_package
IMPORTING
iv_package TYPE devclass.
PRIVATE SECTION.
CLASS-METHODS:
is_adt_jump_possible
IMPORTING io_object TYPE REF TO cl_wb_object
io_adt TYPE REF TO object
RETURNING VALUE(r_is_adt_jump_possible) TYPE abap_bool
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_acid DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS: create_object
RETURNING VALUE(ro_aab) TYPE REF TO cl_aab_id
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_asfc DEFINITION
INHERITING FROM zcl_abapgit_objects_super
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_object .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_object_auth DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_avas DEFINITION
INHERITING FROM zcl_abapgit_objects_super
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_object .
PROTECTED SECTION.
TYPES:
BEGIN OF ty_header,
guid TYPE guid_32,
attribute TYPE cls_attribute_name,
object TYPE pak_object_key,
END OF ty_header .
TYPES:
BEGIN OF ty_avas,
header TYPE ty_header,
values TYPE cls_value_assignments,
links TYPE cls_linked_objects,
END OF ty_avas .
METHODS insert_assignments
IMPORTING
!is_avas TYPE ty_avas
RAISING
zcx_abapgit_exception .
METHODS insert_links
IMPORTING
!is_avas TYPE ty_avas .
METHODS instantiate
RETURNING
VALUE(ro_avas) TYPE REF TO cl_cls_attr_value_assignment
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_object_char DEFINITION
INHERITING FROM zcl_abapgit_objects_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_object .
PRIVATE SECTION.
TYPES:
BEGIN OF ty_char,
cls_attribute TYPE cls_attribute,
cls_attributet TYPE STANDARD TABLE OF cls_attributet WITH DEFAULT KEY,
cls_attr_value TYPE STANDARD TABLE OF cls_attr_value WITH DEFAULT KEY,
cls_attr_valuet TYPE STANDARD TABLE OF cls_attr_valuet WITH DEFAULT KEY,
END OF ty_char .
METHODS instantiate_char
IMPORTING
!iv_type_group TYPE cls_object_type_group
RETURNING
VALUE(ro_char) TYPE REF TO cl_cls_attribute
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_object_cmpt DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
DATA: mo_cmp_db TYPE REF TO object,
mv_name TYPE c LENGTH 30.
ENDCLASS.
CLASS zcl_abapgit_object_cus0 DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
TYPES: tty_img_activity_texts TYPE STANDARD TABLE OF cus_imgact
WITH NON-UNIQUE DEFAULT KEY,
BEGIN OF ty_img_activity,
header TYPE cus_imgach,
texts TYPE tty_img_activity_texts,
END OF ty_img_activity.
DATA: mv_img_activity TYPE cus_img_ac.
ENDCLASS.
CLASS zcl_abapgit_object_cus1 DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
TYPES: tty_activity_titles TYPE STANDARD TABLE OF cus_actt
WITH NON-UNIQUE DEFAULT KEY,
tty_objects TYPE STANDARD TABLE OF cus_actobj
WITH NON-UNIQUE DEFAULT KEY,
tty_objects_title TYPE STANDARD TABLE OF cus_actobt
WITH NON-UNIQUE DEFAULT KEY,
BEGIN OF ty_customzing_activity,
activity_header TYPE cus_acth,
activity_customer_exit TYPE cus_actext,
activity_title TYPE tty_activity_titles,
objects TYPE tty_objects,
objects_title TYPE tty_objects_title,
END OF ty_customzing_activity.
DATA: mv_customizing_activity TYPE cus_img_ac.
ENDCLASS.
CLASS zcl_abapgit_object_cus2 DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
TYPES: tty_attribute_titles TYPE STANDARD TABLE OF cus_atrt
WITH NON-UNIQUE DEFAULT KEY,
tty_attribute_countries TYPE STANDARD TABLE OF cus_atrcou
WITH NON-UNIQUE DEFAULT KEY,
tty_attribute_components TYPE STANDARD TABLE OF tfm18
WITH NON-UNIQUE DEFAULT KEY,
tty_attribute_comp_variants TYPE STANDARD TABLE OF cus_atrvco
WITH NON-UNIQUE DEFAULT KEY.
TYPES: BEGIN OF ty_customizing_attribute,
header TYPE cus_atrh,
titles TYPE tty_attribute_titles,
countries TYPE tty_attribute_countries,
components TYPE tty_attribute_components,
components_variants TYPE tty_attribute_comp_variants,
END OF ty_customizing_attribute.
DATA: mv_img_attribute TYPE cus_atr.
ENDCLASS.
CLASS zcl_abapgit_object_dcls DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_ddls DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PROTECTED SECTION.
METHODS open_adt_stob
IMPORTING iv_ddls_name TYPE tadir-obj_name
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_ddlx DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
DATA: mo_persistence TYPE REF TO if_wb_object_persist.
PRIVATE SECTION.
METHODS:
get_persistence
RETURNING
VALUE(ri_persistence) TYPE REF TO if_wb_object_persist
RAISING
zcx_abapgit_exception,
clear_fields
CHANGING
cs_data TYPE any,
clear_field
IMPORTING
iv_fieldname TYPE csequence
CHANGING
cs_metadata TYPE any.
ENDCLASS.
CLASS zcl_abapgit_object_devc DEFINITION
INHERITING FROM zcl_abapgit_objects_super
FINAL.
PUBLIC SECTION.
INTERFACES:
zif_abapgit_object.
ALIASES:
mo_files FOR zif_abapgit_object~mo_files.
METHODS:
constructor IMPORTING is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PROTECTED SECTION.
PRIVATE SECTION.
METHODS:
get_package RETURNING VALUE(ri_package) TYPE REF TO if_package
RAISING zcx_abapgit_exception,
update_pinf_usages IMPORTING ii_package TYPE REF TO if_package
it_usage_data TYPE scomppdata
RAISING zcx_abapgit_exception,
set_lock IMPORTING ii_package TYPE REF TO if_package
iv_lock TYPE abap_bool
RAISING zcx_abapgit_exception,
is_empty
IMPORTING iv_package_name TYPE devclass
RETURNING VALUE(rv_is_empty) TYPE abap_bool
RAISING zcx_abapgit_exception,
load_package
IMPORTING iv_package_name TYPE devclass
RETURNING VALUE(ri_package) TYPE REF TO if_package
RAISING zcx_abapgit_exception.
DATA:
mv_local_devclass TYPE devclass.
ENDCLASS.
CLASS zcl_abapgit_object_dial DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
TYPES: BEGIN OF ty_dialog_module,
tdct TYPE tdct,
dia_pars TYPE STANDARD TABLE OF diapar
WITH NON-UNIQUE DEFAULT KEY,
END OF ty_dialog_module.
METHODS:
_read_tdct
RETURNING
VALUE(rs_tdct) TYPE tdct.
ENDCLASS.
CLASS zcl_abapgit_object_doct DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
CONSTANTS: c_id TYPE dokhl-id VALUE 'TX',
c_typ TYPE dokhl-typ VALUE 'E',
c_version TYPE dokhl-dokversion VALUE '0001',
c_name TYPE string VALUE 'DOC'.
TYPES: BEGIN OF ty_data,
doctitle TYPE dsyst-doktitle,
head TYPE thead,
lines TYPE tline_tab,
END OF ty_data.
METHODS: read
RETURNING VALUE(rs_data) TYPE ty_data.
ENDCLASS.
CLASS zcl_abapgit_object_docv DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
CONSTANTS: c_typ TYPE dokhl-typ VALUE 'E',
c_version TYPE dokhl-dokversion VALUE '0001',
c_name TYPE string VALUE 'DOC'.
TYPES: BEGIN OF ty_data,
doctitle TYPE dsyst-doktitle,
head TYPE thead,
lines TYPE tline_tab,
END OF ty_data.
METHODS: read
RETURNING VALUE(rs_data) TYPE ty_data.
ENDCLASS.
CLASS zcl_abapgit_object_doma DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES: BEGIN OF ty_dd01_texts,
ddlanguage TYPE dd01v-ddlanguage,
ddtext TYPE dd01v-ddtext,
END OF ty_dd01_texts,
BEGIN OF ty_dd07_texts,
valpos TYPE dd07v-valpos,
ddlanguage TYPE dd07v-ddlanguage,
domvalue_l TYPE dd07v-domvalue_l,
domvalue_h TYPE dd07v-domvalue_h,
ddtext TYPE dd07v-ddtext,
domval_ld TYPE dd07v-domval_ld,
domval_hd TYPE dd07v-domval_hd,
END OF ty_dd07_texts,
tt_dd01_texts TYPE STANDARD TABLE OF ty_dd01_texts,
tt_dd07_texts TYPE STANDARD TABLE OF ty_dd07_texts.
METHODS:
serialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING zcx_abapgit_exception,
deserialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
is_dd01v TYPE dd01v
it_dd07v TYPE dd07v_tab
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_dsys DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
CONSTANTS: c_typ TYPE dokhl-typ VALUE 'E',
c_version TYPE dokhl-dokversion VALUE '0001',
c_id TYPE dokhl-id VALUE 'HY',
c_dokclas TYPE doku_class VALUE 'SIMG'.
DATA: mv_object TYPE dokhl-object,
mv_dokname TYPE doku_obj.
TYPES: BEGIN OF ty_data,
doctitle TYPE dsyst-doktitle,
head TYPE thead,
lines TYPE tline_tab,
END OF ty_data.
METHODS: read
RETURNING VALUE(rs_data) TYPE ty_data.
ENDCLASS.
CLASS zcl_abapgit_object_dtel DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES: BEGIN OF ty_dd04_texts,
ddlanguage TYPE dd04t-ddlanguage,
ddtext TYPE dd04t-ddtext,
reptext TYPE dd04t-reptext,
scrtext_s TYPE dd04t-scrtext_s,
scrtext_m TYPE dd04t-scrtext_m,
scrtext_l TYPE dd04t-scrtext_l,
END OF ty_dd04_texts,
tt_dd04_texts TYPE STANDARD TABLE OF ty_dd04_texts.
METHODS:
serialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING zcx_abapgit_exception,
deserialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
is_dd04v TYPE dd04v
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_ecatt_super DEFINITION
INHERITING FROM zcl_abapgit_objects_super
ABSTRACT
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_object .
ALIASES mo_files
FOR zif_abapgit_object~mo_files .
METHODS:
constructor
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_language TYPE spras .
PROTECTED SECTION.
METHODS:
get_object_type ABSTRACT
RETURNING VALUE(rv_object_type) TYPE etobj_type,
get_upload ABSTRACT
RETURNING
VALUE(ro_upload) TYPE REF TO cl_apl_ecatt_upload,
get_download ABSTRACT
RETURNING
VALUE(ro_download) TYPE REF TO cl_apl_ecatt_download,
get_lock_object ABSTRACT
RETURNING
VALUE(rv_lock_object) TYPE eqeobj.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_last_changed,
luser TYPE xubname,
ldate TYPE datum,
ltime TYPE uzeit,
END OF ty_last_changed.
CONSTANTS:
BEGIN OF co_name,
version TYPE string VALUE 'VERSION' ##NO_TEXT,
versions TYPE string VALUE 'VERSIONS' ##NO_TEXT,
END OF co_name,
co_default_version TYPE etobj_ver VALUE '1' ##NO_TEXT.
CLASS-METHODS:
is_change_more_recent_than
IMPORTING
is_currently_changed TYPE ty_last_changed
is_last_changed TYPE ty_last_changed
RETURNING
VALUE(rv_is_change_more_recent) TYPE abap_bool.
DATA:
mv_object_name TYPE etobj_name.
METHODS:
get_changed_date
IMPORTING
ii_document TYPE REF TO if_ixml_document
RETURNING
VALUE(rv_changed_date) TYPE d,
get_changed_time
IMPORTING
ii_document TYPE REF TO if_ixml_document
RETURNING
VALUE(rv_changed_time) TYPE t,
get_changed_by_user
IMPORTING
ii_document TYPE REF TO if_ixml_document
RETURNING
VALUE(rv_changed_by_user) TYPE xubname,
get_change_information
IMPORTING
is_version_info TYPE etversinfo
RETURNING
VALUE(rs_change_information) TYPE ty_last_changed
RAISING
cx_ecatt_apl
zcx_abapgit_exception,
clear_attributes
CHANGING
ci_document TYPE REF TO if_ixml_document,
clear_elements
CHANGING
ci_document TYPE REF TO if_ixml_document,
get_version_from_node
IMPORTING
ii_node TYPE REF TO if_ixml_node
RETURNING
VALUE(rv_version) TYPE string,
deserialize_version
IMPORTING
ii_version_node TYPE REF TO if_ixml_node
iv_package TYPE devclass
RAISING
zcx_abapgit_exception,
serialize_version
IMPORTING
iv_version TYPE etversinfo-version
CHANGING
ci_node TYPE REF TO if_ixml_element
RAISING
cx_ecatt
zcx_abapgit_exception,
clear_element
IMPORTING
iv_name TYPE csequence
CHANGING
ci_document TYPE REF TO if_ixml_document,
serialize_versions
IMPORTING
it_version_info TYPE etversinfo_tabtype
CHANGING
ci_document TYPE REF TO if_ixml_document
RAISING
cx_ecatt
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_ecat DEFINITION
INHERITING FROM zcl_abapgit_object_ecatt_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_language TYPE spras.
PROTECTED SECTION.
METHODS:
get_object_type REDEFINITION,
get_upload REDEFINITION,
get_download REDEFINITION,
get_lock_object REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_ecsd DEFINITION
INHERITING FROM zcl_abapgit_object_ecatt_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_language TYPE spras.
PROTECTED SECTION.
METHODS:
get_object_type REDEFINITION,
get_upload REDEFINITION,
get_download REDEFINITION,
get_lock_object REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_ecsp DEFINITION
INHERITING FROM zcl_abapgit_object_ecatt_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_language TYPE spras.
PROTECTED SECTION.
METHODS:
get_object_type REDEFINITION,
get_upload REDEFINITION,
get_download REDEFINITION,
get_lock_object REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_ectc DEFINITION
INHERITING FROM zcl_abapgit_object_ecatt_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_language TYPE spras.
PROTECTED SECTION.
METHODS:
get_object_type REDEFINITION,
get_upload REDEFINITION,
get_download REDEFINITION,
get_lock_object REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_ectd DEFINITION
INHERITING FROM zcl_abapgit_object_ecatt_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_language TYPE spras.
PROTECTED SECTION.
METHODS:
get_object_type REDEFINITION,
get_upload REDEFINITION,
get_download REDEFINITION,
get_lock_object REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_ecvo DEFINITION
INHERITING FROM zcl_abapgit_object_ecatt_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_language TYPE spras.
PROTECTED SECTION.
METHODS:
get_object_type REDEFINITION,
get_upload REDEFINITION,
get_download REDEFINITION,
get_lock_object REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_enho DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS:
factory
IMPORTING
iv_tool TYPE enhtooltype
RETURNING
VALUE(ri_enho) TYPE REF TO zif_abapgit_object_enho
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_enhs DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS:
factory
IMPORTING
iv_tool TYPE enhtooltype
RETURNING
VALUE(ri_enho) TYPE REF TO zif_abapgit_object_enhs
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_enqu DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_ensc DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_form DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
CONSTANTS: c_objectname_form TYPE thead-tdobject VALUE 'FORM' ##NO_TEXT.
CONSTANTS: c_objectname_tdlines TYPE thead-tdobject VALUE 'TDLINES' ##NO_TEXT.
CONSTANTS: c_extension_xml TYPE string VALUE 'xml' ##NO_TEXT.
TYPES: BEGIN OF tys_form_data,
form_header TYPE itcta,
text_header TYPE thead,
orig_language TYPE sy-langu,
pages TYPE STANDARD TABLE OF itctg WITH DEFAULT KEY,
page_windows TYPE STANDARD TABLE OF itcth WITH DEFAULT KEY,
paragraphs TYPE STANDARD TABLE OF itcdp WITH DEFAULT KEY,
strings TYPE STANDARD TABLE OF itcds WITH DEFAULT KEY,
tabs TYPE STANDARD TABLE OF itcdq WITH DEFAULT KEY,
windows TYPE STANDARD TABLE OF itctw WITH DEFAULT KEY,
END OF tys_form_data,
tyt_form_data TYPE STANDARD TABLE OF tys_form_data WITH DEFAULT KEY,
tyt_form_header TYPE STANDARD TABLE OF itcta WITH DEFAULT KEY,
tys_form_header TYPE LINE OF tyt_form_header,
tyt_text_header TYPE STANDARD TABLE OF thead WITH DEFAULT KEY,
tys_text_header TYPE LINE OF tyt_text_header,
tyt_lines TYPE tline_tab.
METHODS get_last_changes
IMPORTING
iv_form_name TYPE zif_abapgit_definitions=>ty_item-obj_name
RETURNING
VALUE(rs_last_changed) TYPE tys_form_header.
METHODS build_extra_from_header
IMPORTING
is_header TYPE tys_form_header
RETURNING
VALUE(rv_result) TYPE string.
METHODS build_extra_from_header_old
IMPORTING
is_header TYPE tys_form_header
RETURNING
VALUE(rv_result) TYPE string.
METHODS _save_form
IMPORTING
it_lines TYPE zcl_abapgit_object_form=>tyt_lines
CHANGING
cs_form_data TYPE zcl_abapgit_object_form=>tys_form_data.
METHODS extract_tdlines
IMPORTING
is_form_data TYPE zcl_abapgit_object_form=>tys_form_data
RETURNING
VALUE(rt_lines) TYPE zcl_abapgit_object_form=>tyt_lines
RAISING
zcx_abapgit_exception.
METHODS _clear_changed_fields
CHANGING
cs_form_data TYPE zcl_abapgit_object_form=>tys_form_data.
METHODS compress_lines
IMPORTING
is_form_data TYPE zcl_abapgit_object_form=>tys_form_data
it_lines TYPE zcl_abapgit_object_form=>tyt_lines
RAISING
zcx_abapgit_exception.
METHODS find_form
IMPORTING
iv_object_name TYPE zif_abapgit_definitions=>ty_item-obj_name
RETURNING
VALUE(rt_text_header) TYPE zcl_abapgit_object_form=>tyt_text_header.
METHODS _read_form
IMPORTING
is_text_header TYPE zcl_abapgit_object_form=>tys_text_header
EXPORTING
ev_form_found TYPE flag
es_form_data TYPE zcl_abapgit_object_form=>tys_form_data
et_lines TYPE zcl_abapgit_object_form=>tyt_lines.
ENDCLASS.
CLASS zcl_abapgit_object_iamu DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES: BEGIN OF ty_internet_appl_comp_binary,
attributes TYPE w3mimeattr,
source TYPE w3mimetabtype,
length TYPE i,
END OF ty_internet_appl_comp_binary.
DATA: mo_mime_api TYPE REF TO if_w3_api_mime.
METHODS:
load_mime_api
RAISING
zcx_abapgit_exception,
read
RETURNING
VALUE(rs_internet_appl_comp_binary) TYPE ty_internet_appl_comp_binary
RAISING
zcx_abapgit_exception,
save
IMPORTING
is_internet_appl_comp_binary TYPE ty_internet_appl_comp_binary
RAISING
zcx_abapgit_exception,
release_lock
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_iarp DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS:
read
EXPORTING es_attr TYPE w3resoattr
et_parameters TYPE w3resopara_tabletype
RAISING zcx_abapgit_exception,
save
IMPORTING is_attr TYPE w3resoattr
it_parameters TYPE w3resopara_tabletype
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_iasp DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS:
read
EXPORTING es_attr TYPE w3servattr
et_parameters TYPE w3servpara_tabletype
RAISING zcx_abapgit_exception,
save
IMPORTING is_attr TYPE w3servattr
it_parameters TYPE w3servpara_tabletype
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_iatu DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS:
read
EXPORTING es_attr TYPE w3tempattr
ev_source TYPE string
RAISING zcx_abapgit_exception,
save
IMPORTING is_attr TYPE w3tempattr
iv_source TYPE string
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_idoc DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS:
constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_idoc,
attributes TYPE edi_iapi01,
t_syntax TYPE STANDARD TABLE OF edi_iapi02 WITH NON-UNIQUE DEFAULT KEY,
END OF ty_idoc.
DATA:
mv_idoctyp TYPE edi_iapi00-idoctyp.
ENDCLASS.
CLASS zcl_abapgit_object_iext DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS:
constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_extention,
attributes TYPE edi_iapi01,
t_syntax TYPE STANDARD TABLE OF edi_iapi03 WITH NON-UNIQUE DEFAULT KEY,
END OF ty_extention.
DATA:
mv_extension TYPE edi_cimtyp.
ENDCLASS.
CLASS zcl_abapgit_object_jobd DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
TYPES: ty_jd_name TYPE c LENGTH 32.
ENDCLASS.
CLASS zcl_abapgit_object_msag DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES: BEGIN OF ty_t100_texts,
sprsl TYPE t100-sprsl,
msgnr TYPE t100-msgnr,
text TYPE t100-text,
END OF ty_t100_texts,
tt_t100_texts TYPE STANDARD TABLE OF ty_t100_texts.
METHODS:
serialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING zcx_abapgit_exception,
deserialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_nrob DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS:
delete_intervals IMPORTING iv_object TYPE inri-object
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_para DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_pinf DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
TYPES: BEGIN OF ty_pinf,
attributes TYPE scompidtln,
elements TYPE STANDARD TABLE OF scomeldtln WITH DEFAULT KEY,
END OF ty_pinf.
TYPES: ty_elements TYPE STANDARD TABLE OF tpak_package_interf_elem_ref WITH DEFAULT KEY.
METHODS:
create_or_load
IMPORTING is_pinf TYPE ty_pinf
iv_package TYPE devclass
RETURNING VALUE(ri_interface) TYPE REF TO if_package_interface
RAISING zcx_abapgit_exception,
delete_elements
IMPORTING ii_interface TYPE REF TO if_package_interface
RAISING zcx_abapgit_exception,
update_attributes
IMPORTING is_pinf TYPE ty_pinf
ii_interface TYPE REF TO if_package_interface
RAISING zcx_abapgit_exception,
update_elements
IMPORTING is_pinf TYPE ty_pinf
ii_interface TYPE REF TO if_package_interface
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_prag DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
TYPES: BEGIN OF ty_pragma,
pragma TYPE c LENGTH 40,
extension TYPE c LENGTH 1,
signature TYPE c LENGTH 10,
description TYPE c LENGTH 255,
END OF ty_pragma.
METHODS:
_raise_pragma_not_exists
RAISING
zcx_abapgit_exception,
_raise_pragma_exists
RAISING
zcx_abapgit_exception,
_raise_pragma_enqueue
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_scp1 DEFINITION
INHERITING FROM zcl_abapgit_objects_super
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_object .
PROTECTED SECTION.
TYPES:
BEGIN OF ty_scp1,
scprattr TYPE scprattr,
scprtext TYPE STANDARD TABLE OF scprtext WITH DEFAULT KEY,
scprvals TYPE STANDARD TABLE OF scprvals WITH DEFAULT KEY,
scprvall TYPE STANDARD TABLE OF scprvall WITH DEFAULT KEY,
scprreca TYPE STANDARD TABLE OF scprreca WITH DEFAULT KEY,
scprfldv TYPE STANDARD TABLE OF scprfldv WITH DEFAULT KEY,
END OF ty_scp1 .
METHODS dequeue .
METHODS enqueue
RAISING
zcx_abapgit_exception .
METHODS save
IMPORTING
!is_scp1 TYPE ty_scp1
RAISING
zcx_abapgit_exception .
METHODS adjust_inbound
CHANGING
!cs_scp1 TYPE ty_scp1 .
METHODS adjust_outbound
CHANGING
!cs_scp1 TYPE ty_scp1 .
METHODS load
CHANGING
!cs_scp1 TYPE ty_scp1 .
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_object_sfbf DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
METHODS:
get
RETURNING VALUE(ro_bf) TYPE REF TO cl_sfw_bf
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_sfbs DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
METHODS:
get
RETURNING VALUE(ro_bfs) TYPE REF TO cl_sfw_bfs
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_sfpf DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
CLASS-METHODS:
fix_oref
IMPORTING ii_document TYPE REF TO if_ixml_document.
PRIVATE SECTION.
METHODS:
load
RETURNING VALUE(ri_wb_form) TYPE REF TO if_fp_wb_form
RAISING zcx_abapgit_exception,
form_to_xstring
RETURNING VALUE(rv_xstr) TYPE xstring
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_sfpi DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS:
load
RETURNING VALUE(ri_wb_interface) TYPE REF TO if_fp_wb_interface
RAISING zcx_abapgit_exception,
interface_to_xstring
RETURNING VALUE(rv_xstr) TYPE xstring
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_sfsw DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
METHODS:
get
RETURNING VALUE(ro_switch) TYPE REF TO cl_sfw_sw
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_shi3 DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
DATA: mv_tree_id TYPE ttree-id.
METHODS jump_se43
RAISING zcx_abapgit_exception.
METHODS clear_fields
CHANGING cs_head TYPE ttree
ct_nodes TYPE hier_iface_t.
ENDCLASS.
CLASS zcl_abapgit_object_shi5 DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
TYPES: tty_ttree_extt TYPE STANDARD TABLE OF ttree_extt
WITH NON-UNIQUE DEFAULT KEY,
BEGIN OF ty_extension,
header TYPE ttree_ext,
texts TYPE tty_ttree_extt,
END OF ty_extension.
DATA: mv_extension TYPE hier_names.
ENDCLASS.
CLASS zcl_abapgit_object_shi8 DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
DATA: mv_assignment_id TYPE hier_sfw_id.
ENDCLASS.
CLASS zcl_abapgit_object_shlp DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_shma DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ENDCLASS.
CLASS zcl_abapgit_object_sicf DEFINITION
INHERITING FROM zcl_abapgit_objects_super
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_object .
ALIASES mo_files
FOR zif_abapgit_object~mo_files .
CLASS-METHODS read_tadir_sicf
IMPORTING
!iv_pgmid TYPE tadir-pgmid DEFAULT 'R3TR'
!iv_obj_name TYPE tadir-obj_name
RETURNING
VALUE(rs_tadir) TYPE zif_abapgit_definitions=>ty_tadir
RAISING
zcx_abapgit_exception .
CLASS-METHODS read_sicf_url
IMPORTING
!iv_obj_name TYPE tadir-obj_name
RETURNING
VALUE(rv_hash) TYPE text25
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
TYPES:
ty_icfhandler_tt TYPE STANDARD TABLE OF icfhandler WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_sicf_key,
icf_name TYPE icfservice-icf_name,
icfparguid TYPE icfservice-icfparguid,
END OF ty_sicf_key .
METHODS read
IMPORTING
!iv_clear TYPE abap_bool DEFAULT abap_true
EXPORTING
!es_icfservice TYPE icfservice
!es_icfdocu TYPE icfdocu
!et_icfhandler TYPE ty_icfhandler_tt
!ev_url TYPE string
RAISING
zcx_abapgit_exception .
METHODS insert_sicf
IMPORTING
!is_icfservice TYPE icfservice
!is_icfdocu TYPE icfdocu
!it_icfhandler TYPE ty_icfhandler_tt
!iv_package TYPE devclass
!iv_url TYPE string
RAISING
zcx_abapgit_exception .
METHODS change_sicf
IMPORTING
!is_icfservice TYPE icfservice
!is_icfdocu TYPE icfdocu
!it_icfhandler TYPE ty_icfhandler_tt
!iv_package TYPE devclass
!iv_parent TYPE icfparguid
RAISING
zcx_abapgit_exception .
METHODS to_icfhndlist
IMPORTING
!it_list TYPE ty_icfhandler_tt
RETURNING
VALUE(rt_list) TYPE icfhndlist .
METHODS find_parent
IMPORTING
!iv_url TYPE string
RETURNING
VALUE(rv_parent) TYPE icfparguid
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_object_smim DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS get_filename
IMPORTING iv_url TYPE string
RETURNING VALUE(rv_filename) TYPE string.
METHODS find_content
IMPORTING iv_url TYPE string
RETURNING VALUE(rv_content) TYPE xstring
RAISING zcx_abapgit_exception.
METHODS build_filename
IMPORTING iv_filename TYPE string
RETURNING VALUE(rv_filename) TYPE string.
METHODS get_url_for_io
EXPORTING ev_url TYPE string
ev_is_folder TYPE boole_d
RAISING zcx_abapgit_not_found
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_splo DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_srfc DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ENDCLASS.
CLASS zcl_abapgit_object_ssfo DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS: fix_ids IMPORTING ii_xml_doc TYPE REF TO if_ixml_document.
ENDCLASS.
CLASS zcl_abapgit_object_ssst DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
CONSTANTS: c_style_active TYPE tdactivate VALUE 'A'.
PRIVATE SECTION.
METHODS validate_font
IMPORTING iv_tdfamily TYPE tdfamily
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_styl DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES: BEGIN OF ty_style,
header TYPE itcda,
paragraphs TYPE STANDARD TABLE OF itcdp WITH DEFAULT KEY,
strings TYPE STANDARD TABLE OF itcds WITH DEFAULT KEY,
tabs TYPE STANDARD TABLE OF itcdq WITH DEFAULT KEY,
END OF ty_style.
ENDCLASS.
CLASS zcl_abapgit_object_susc DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_suso DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_sxci DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
TYPES: BEGIN OF ty_classic_badi_implementation,
implementation_data TYPE impl_data,
function_codes TYPE seex_fcode_table,
control_composites TYPE seex_coco_table,
customer_includes TYPE seex_table_table,
screens TYPE seex_screen_table,
filters TYPE seex_filter_table,
END OF ty_classic_badi_implementation.
ENDCLASS.
CLASS zcl_abapgit_object_tabl DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_tobj DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES: BEGIN OF ty_tobj,
tddat TYPE tddat,
tvdir TYPE tvdir,
tvimf TYPE STANDARD TABLE OF tvimf WITH DEFAULT KEY,
END OF ty_tobj.
METHODS:
read_extra IMPORTING iv_tabname TYPE vim_name
RETURNING VALUE(rs_tobj) TYPE ty_tobj,
update_extra IMPORTING is_tobj TYPE ty_tobj,
delete_extra IMPORTING iv_tabname TYPE vim_name.
ENDCLASS.
CLASS zcl_abapgit_object_tran DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
CONSTANTS: c_oo_program(9) VALUE '\PROGRAM=',
c_oo_class(7) VALUE '\CLASS=',
c_oo_method(8) VALUE '\METHOD=',
c_oo_tcode TYPE tcode VALUE 'OS_APPLICATION',
c_oo_frclass(30) VALUE 'CLASS',
c_oo_frmethod(30) VALUE 'METHOD',
c_oo_frupdtask(30) VALUE 'UPDATE_MODE',
c_oo_synchron VALUE 'S',
c_oo_asynchron VALUE 'U',
c_true TYPE c VALUE 'X',
c_false TYPE c VALUE space.
METHODS:
split_parameters
CHANGING ct_rsparam TYPE s_param
cs_rsstcd TYPE rsstcd
cs_tstcp TYPE tstcp
cs_tstc TYPE tstc,
split_parameters_comp
IMPORTING ig_type TYPE any
ig_param TYPE any
CHANGING cg_value TYPE any,
serialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING zcx_abapgit_exception,
deserialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_ttyp DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_type DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
CONSTANTS: c_prefix TYPE c LENGTH 3 VALUE '%_C'.
METHODS read
EXPORTING ev_ddtext TYPE ddtypet-ddtext
et_source TYPE abaptxt255_tab
RAISING zcx_abapgit_exception
zcx_abapgit_not_found.
METHODS create
IMPORTING iv_ddtext TYPE ddtypet-ddtext
it_source TYPE abaptxt255_tab
iv_devclass TYPE devclass
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_ucsa DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
TYPES:
ty_id TYPE c LENGTH 30.
METHODS:
get_persistence
IMPORTING
iv_id TYPE ty_id
RETURNING
VALUE(ro_persistence) TYPE REF TO object,
clear_dynamic_fields
CHANGING
cg_complete_comm_assembly TYPE any,
clear_field
IMPORTING
iv_fieldname TYPE csequence
CHANGING
cg_header TYPE any.
ENDCLASS.
CLASS zcl_abapgit_object_vcls DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
CONSTANTS: c_cluster_type TYPE c VALUE 'C'.
CONSTANTS: c_mode_insert TYPE obj_para-maint_mode VALUE 'I'.
ENDCLASS.
CLASS zcl_abapgit_object_view DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
ENDCLASS.
CLASS zcl_abapgit_object_w3super DEFINITION INHERITING FROM zcl_abapgit_objects_super ABSTRACT.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
TYPES ty_wwwparams_tt TYPE STANDARD TABLE OF wwwparams WITH DEFAULT KEY.
CONSTANTS: BEGIN OF c_param_names,
version TYPE w3_name VALUE 'version',
fileext TYPE w3_name VALUE 'fileextension',
filesize TYPE w3_name VALUE 'filesize',
filename TYPE w3_name VALUE 'filename',
mimetype TYPE w3_name VALUE 'mimetype',
END OF c_param_names.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PROTECTED SECTION.
TYPES tty_bdcdata TYPE STANDARD TABLE OF bdcdata
WITH NON-UNIQUE DEFAULT KEY.
METHODS get_metadata REDEFINITION.
METHODS change_bdc_jump_data ABSTRACT
CHANGING
ct_bdcdata TYPE tty_bdcdata.
PRIVATE SECTION.
DATA ms_key TYPE wwwdatatab.
METHODS get_ext
IMPORTING it_params TYPE ty_wwwparams_tt
RETURNING VALUE(rv_ext) TYPE string
RAISING zcx_abapgit_exception.
METHODS normalize_params
IMPORTING iv_size TYPE i
CHANGING ct_params TYPE ty_wwwparams_tt " Param table to patch
RAISING zcx_abapgit_exception.
METHODS strip_params
CHANGING ct_params TYPE ty_wwwparams_tt
RAISING zcx_abapgit_exception.
METHODS find_param
IMPORTING it_params TYPE ty_wwwparams_tt
iv_name TYPE w3_name
RETURNING VALUE(rv_value) TYPE string
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_w3ht DEFINITION INHERITING FROM zcl_abapgit_object_w3super FINAL.
PROTECTED SECTION.
METHODS: change_bdc_jump_data REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_w3mi DEFINITION INHERITING FROM zcl_abapgit_object_w3super FINAL.
PROTECTED SECTION.
METHODS: change_bdc_jump_data REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_wapa DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES: BEGIN OF ty_page,
attributes TYPE o2pagattr,
event_handlers TYPE o2pagevh_tabletype,
parameters TYPE o2pagpar_tabletype,
types TYPE rswsourcet,
END OF ty_page.
TYPES: ty_pages_tt TYPE STANDARD TABLE OF ty_page WITH DEFAULT KEY.
CONSTANTS: c_active TYPE so2_version VALUE 'A'.
METHODS:
get_page_content
IMPORTING io_page TYPE REF TO cl_o2_api_pages
RETURNING VALUE(rv_content) TYPE xstring
RAISING zcx_abapgit_exception,
to_page_content
IMPORTING iv_content TYPE xstring
RETURNING VALUE(rt_content) TYPE o2pageline_table,
read_page
IMPORTING is_page TYPE o2pagattr
RETURNING VALUE(rs_page) TYPE ty_page
RAISING zcx_abapgit_exception,
create_new_application
IMPORTING is_attributes TYPE o2applattr
it_nodes TYPE o2applnode_table
it_navgraph TYPE o2applgrap_table
RETURNING VALUE(ro_bsp) TYPE REF TO cl_o2_api_application
RAISING zcx_abapgit_exception,
create_new_page
IMPORTING
is_page_attributes TYPE o2pagattr
RETURNING
VALUE(ro_page) TYPE REF TO cl_o2_api_pages
RAISING
zcx_abapgit_exception,
delete_superfluous_pages
IMPORTING
it_local_pages TYPE o2pagelist
it_remote_pages TYPE zcl_abapgit_object_wapa=>ty_pages_tt
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_wdya DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS read
EXPORTING es_app TYPE wdy_application
et_properties TYPE wdy_app_property_table
RAISING zcx_abapgit_exception.
METHODS save
IMPORTING is_app TYPE wdy_application
it_properties TYPE wdy_app_property_table
iv_package TYPE devclass
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_wdyn DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
DATA:
mt_components TYPE TABLE OF wdy_ctlr_compo_vrs,
mt_sources TYPE TABLE OF wdy_ctlr_compo_source_vrs.
METHODS:
get_limu_objects
RETURNING VALUE(rt_objects) TYPE wdy_md_transport_keys,
read
RETURNING VALUE(rs_component) TYPE wdy_component_metadata
RAISING zcx_abapgit_exception,
read_controller
IMPORTING is_key TYPE wdy_md_controller_key
RETURNING VALUE(rs_controller) TYPE wdy_md_controller_meta_data
RAISING zcx_abapgit_exception,
read_definition
IMPORTING is_key TYPE wdy_md_component_key
RETURNING VALUE(rs_definition) TYPE wdy_md_component_meta_data
RAISING zcx_abapgit_exception,
read_view
IMPORTING is_key TYPE wdy_md_view_key
RETURNING VALUE(rs_view) TYPE wdy_md_view_meta_data
RAISING zcx_abapgit_exception,
recover_controller
IMPORTING is_controller TYPE wdy_md_controller_meta_data
RAISING zcx_abapgit_exception,
recover_definition
IMPORTING is_definition TYPE wdy_md_component_meta_data
iv_package TYPE devclass
RAISING zcx_abapgit_exception,
recover_view
IMPORTING is_view TYPE wdy_md_view_meta_data
RAISING zcx_abapgit_exception,
delta_controller
IMPORTING is_controller TYPE wdy_md_controller_meta_data
RETURNING VALUE(rs_delta) TYPE svrs2_xversionable_object
RAISING zcx_abapgit_exception,
delta_definition
IMPORTING is_definition TYPE wdy_md_component_meta_data
VALUE(iv_package) TYPE devclass
RETURNING VALUE(rs_delta) TYPE svrs2_xversionable_object
RAISING zcx_abapgit_exception,
delta_view
IMPORTING is_view TYPE wdy_md_view_meta_data
RETURNING VALUE(rs_delta) TYPE svrs2_xversionable_object
RAISING zcx_abapgit_exception,
add_fm_param_exporting
IMPORTING iv_name TYPE string
ig_value TYPE any
CHANGING ct_param TYPE abap_func_parmbind_tab,
add_fm_param_tables
IMPORTING iv_name TYPE string
CHANGING ct_value TYPE ANY TABLE
ct_param TYPE abap_func_parmbind_tab,
add_fm_exception
IMPORTING iv_name TYPE string
iv_value TYPE i
CHANGING ct_exception TYPE abap_func_excpbind_tab.
ENDCLASS.
CLASS zcl_abapgit_object_webi DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
PRIVATE SECTION.
TYPES: BEGIN OF ty_webi,
veptext TYPE veptext,
pvepheader TYPE STANDARD TABLE OF vepheader WITH DEFAULT KEY,
pvepfunction TYPE STANDARD TABLE OF vepfunction WITH DEFAULT KEY,
pvepfault TYPE STANDARD TABLE OF vepfault WITH DEFAULT KEY,
pvepparameter TYPE STANDARD TABLE OF vepparameter WITH DEFAULT KEY,
pveptype TYPE STANDARD TABLE OF veptype WITH DEFAULT KEY,
pvepelemtype TYPE STANDARD TABLE OF vepelemtype WITH DEFAULT KEY,
pveptabletype TYPE STANDARD TABLE OF veptabletype WITH DEFAULT KEY,
pvepstrutype TYPE STANDARD TABLE OF vepstrutype WITH DEFAULT KEY,
pveptypesoapext TYPE STANDARD TABLE OF veptypesoapext WITH DEFAULT KEY,
pvepeletypsoap TYPE STANDARD TABLE OF vepeletypsoap WITH DEFAULT KEY,
pveptabtypsoap TYPE STANDARD TABLE OF veptabtypsoap WITH DEFAULT KEY,
pvepfuncsoapext TYPE STANDARD TABLE OF vepfuncsoapext WITH DEFAULT KEY,
pvepfieldref TYPE STANDARD TABLE OF vepfieldref WITH DEFAULT KEY,
pvependpoint TYPE STANDARD TABLE OF vependpoint WITH DEFAULT KEY,
pvepvisoapext TYPE STANDARD TABLE OF vepvisoapext WITH DEFAULT KEY,
pvepparasoapext TYPE STANDARD TABLE OF vepparasoapext WITH DEFAULT KEY,
END OF ty_webi.
DATA: mi_vi TYPE REF TO if_ws_md_vif.
METHODS:
handle_endpoint
IMPORTING is_webi TYPE ty_webi
RAISING zcx_abapgit_exception
cx_ws_md_exception,
handle_types
IMPORTING is_webi TYPE ty_webi
RAISING zcx_abapgit_exception
cx_ws_md_exception,
handle_soap
IMPORTING is_webi TYPE ty_webi
RAISING zcx_abapgit_exception
cx_ws_md_exception,
handle_function
IMPORTING is_webi TYPE ty_webi
RAISING zcx_abapgit_exception
cx_ws_md_exception.
ENDCLASS.
CLASS zcl_abapgit_object_xinx DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS:
constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PRIVATE SECTION.
TYPES: BEGIN OF ty_extension_index,
dd12v TYPE dd12v,
t_dd17v TYPE STANDARD TABLE OF dd17v
WITH NON-UNIQUE DEFAULT KEY,
END OF ty_extension_index.
DATA:
mv_name TYPE ddobjname,
mv_id TYPE ddobjectid.
ENDCLASS.
CLASS zcl_abapgit_object_xslt DEFINITION INHERITING FROM zcl_abapgit_objects_super FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
METHODS:
get
RETURNING VALUE(ro_xslt) TYPE REF TO cl_o2_api_xsltdesc
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_objects_program DEFINITION INHERITING FROM zcl_abapgit_objects_super.
PUBLIC SECTION.
TYPES: BEGIN OF ty_progdir,
name TYPE progdir-name,
state TYPE progdir-state,
sqlx TYPE progdir-sqlx,
edtx TYPE progdir-edtx,
varcl TYPE progdir-varcl,
dbapl TYPE progdir-dbapl,
dbna TYPE progdir-dbna,
clas TYPE progdir-clas,
type TYPE progdir-type,
occurs TYPE progdir-occurs,
subc TYPE progdir-subc,
appl TYPE progdir-appl,
secu TYPE progdir-secu,
cnam TYPE progdir-cnam,
cdat TYPE progdir-cdat,
unam TYPE progdir-unam,
udat TYPE progdir-udat,
vern TYPE progdir-vern,
levl TYPE progdir-levl,
rstat TYPE progdir-rstat,
rmand TYPE progdir-rmand,
rload TYPE progdir-rload,
fixpt TYPE progdir-fixpt,
sset TYPE progdir-sset,
sdate TYPE progdir-sdate,
stime TYPE progdir-stime,
idate TYPE progdir-idate,
itime TYPE progdir-itime,
ldbname TYPE progdir-ldbname,
uccheck TYPE progdir-uccheck,
END OF ty_progdir.
METHODS serialize_program
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output OPTIONAL
is_item TYPE zif_abapgit_definitions=>ty_item
io_files TYPE REF TO zcl_abapgit_objects_files
iv_program TYPE programm OPTIONAL
iv_extra TYPE clike OPTIONAL
RAISING zcx_abapgit_exception.
METHODS read_progdir
IMPORTING iv_program TYPE programm
RETURNING VALUE(rs_progdir) TYPE ty_progdir.
METHODS deserialize_program
IMPORTING is_progdir TYPE ty_progdir
it_source TYPE abaptxt255_tab
it_tpool TYPE textpool_table
iv_package TYPE devclass
RAISING zcx_abapgit_exception.
PROTECTED SECTION.
TYPES: ty_spaces_tt TYPE STANDARD TABLE OF i WITH DEFAULT KEY.
TYPES: BEGIN OF ty_dynpro,
header TYPE rpy_dyhead,
containers TYPE dycatt_tab,
fields TYPE dyfatc_tab,
flow_logic TYPE swydyflow,
spaces TYPE ty_spaces_tt,
END OF ty_dynpro.
TYPES: ty_dynpro_tt TYPE STANDARD TABLE OF ty_dynpro WITH DEFAULT KEY.
TYPES: BEGIN OF ty_cua,
adm TYPE rsmpe_adm,
sta TYPE STANDARD TABLE OF rsmpe_stat WITH DEFAULT KEY,
fun TYPE STANDARD TABLE OF rsmpe_funt WITH DEFAULT KEY,
men TYPE STANDARD TABLE OF rsmpe_men WITH DEFAULT KEY,
mtx TYPE STANDARD TABLE OF rsmpe_mnlt WITH DEFAULT KEY,
act TYPE STANDARD TABLE OF rsmpe_act WITH DEFAULT KEY,
but TYPE STANDARD TABLE OF rsmpe_but WITH DEFAULT KEY,
pfk TYPE STANDARD TABLE OF rsmpe_pfk WITH DEFAULT KEY,
set TYPE STANDARD TABLE OF rsmpe_staf WITH DEFAULT KEY,
doc TYPE STANDARD TABLE OF rsmpe_atrt WITH DEFAULT KEY,
tit TYPE STANDARD TABLE OF rsmpe_titt WITH DEFAULT KEY,
biv TYPE STANDARD TABLE OF rsmpe_buts WITH DEFAULT KEY,
END OF ty_cua.
METHODS serialize_dynpros
IMPORTING iv_program_name TYPE programm
RETURNING VALUE(rt_dynpro) TYPE ty_dynpro_tt
RAISING zcx_abapgit_exception.
METHODS serialize_cua
IMPORTING iv_program_name TYPE programm
RETURNING VALUE(rs_cua) TYPE ty_cua
RAISING zcx_abapgit_exception.
METHODS deserialize_dynpros
IMPORTING it_dynpros TYPE ty_dynpro_tt
RAISING zcx_abapgit_exception.
METHODS deserialize_textpool
IMPORTING iv_program TYPE programm
it_tpool TYPE textpool_table
iv_language TYPE langu OPTIONAL
iv_is_include TYPE abap_bool DEFAULT abap_false
RAISING zcx_abapgit_exception.
METHODS deserialize_cua
IMPORTING iv_program_name TYPE programm
is_cua TYPE ty_cua
RAISING zcx_abapgit_exception.
METHODS check_prog_changed_since
IMPORTING iv_program TYPE programm
iv_timestamp TYPE timestamp
iv_skip_gui TYPE abap_bool DEFAULT abap_false
RETURNING VALUE(rv_changed) TYPE abap_bool.
METHODS is_any_dynpro_locked
IMPORTING iv_program TYPE programm
RETURNING VALUE(rv_is_any_dynpro_locked) TYPE abap_bool
RAISING zcx_abapgit_exception.
METHODS is_cua_locked
IMPORTING iv_program TYPE programm
RETURNING VALUE(rv_is_cua_locked) TYPE abap_bool
RAISING zcx_abapgit_exception.
METHODS is_text_locked
IMPORTING iv_program TYPE programm
RETURNING VALUE(rv_is_text_locked) TYPE abap_bool
RAISING zcx_abapgit_exception.
CLASS-METHODS:
add_tpool
IMPORTING it_tpool TYPE textpool_table
RETURNING VALUE(rt_tpool) TYPE zif_abapgit_definitions=>ty_tpool_tt,
read_tpool
IMPORTING it_tpool TYPE zif_abapgit_definitions=>ty_tpool_tt
RETURNING VALUE(rt_tpool) TYPE zif_abapgit_definitions=>ty_tpool_tt.
PRIVATE SECTION.
METHODS:
condense_flow
EXPORTING et_spaces TYPE ty_spaces_tt
CHANGING ct_flow TYPE swydyflow,
uncondense_flow
IMPORTING it_flow TYPE swydyflow
it_spaces TYPE ty_spaces_tt
RETURNING VALUE(rt_flow) TYPE swydyflow.
CLASS-METHODS auto_correct_cua_adm
IMPORTING
is_cua TYPE zcl_abapgit_objects_program=>ty_cua
CHANGING
cs_adm TYPE rsmpe_adm.
ENDCLASS.
CLASS zcl_abapgit_object_clas_old DEFINITION INHERITING FROM zcl_abapgit_objects_program.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PROTECTED SECTION.
DATA: mi_object_oriented_object_fct TYPE REF TO zif_abapgit_oo_object_fnc,
mv_skip_testclass TYPE abap_bool.
METHODS:
deserialize_abap
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
iv_package TYPE devclass
RAISING zcx_abapgit_exception,
deserialize_docu
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING zcx_abapgit_exception,
deserialize_tpool
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING zcx_abapgit_exception,
deserialize_sotr
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
iv_package TYPE devclass
RAISING zcx_abapgit_exception,
serialize_xml
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
METHODS:
is_class_locked
RETURNING VALUE(rv_is_class_locked) TYPE abap_bool
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_clas DEFINITION INHERITING FROM zcl_abapgit_object_clas_old.
PUBLIC SECTION.
METHODS: constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PROTECTED SECTION.
METHODS:
deserialize_abap REDEFINITION.
ENDCLASS.
"! This class is just a different name for zcl_zabapgit_object_clas.
"! It has been created to heal repositories of the brave ones who uses abapGit
"! experimental features "! and had the luck to serialize their CLAS objects with
"! the serializer LCL_OBJECT_CLAS_NEW.
"! It can be removed on 2019-04 where we expect all CLAS object being
"! re-serialized with the serializer LCL_OBJECT_CLAS.
"! References: https://github.com/larshp/abapGit/pull/1311
CLASS zcl_abapgit_object_clas_new DEFINITION INHERITING FROM zcl_abapgit_object_clas.
PROTECTED SECTION.
METHODS:
get_metadata REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_fugr DEFINITION INHERITING FROM zcl_abapgit_objects_program FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES:
ty_rs38l_incl_tt TYPE STANDARD TABLE OF rs38l_incl WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_function,
funcname TYPE rs38l_fnam,
global_flag TYPE rs38l-global,
remote_call TYPE rs38l-remote,
update_task TYPE rs38l-utask,
short_text TYPE tftit-stext,
remote_basxml TYPE rs38l-basxml_enabled,
import TYPE STANDARD TABLE OF rsimp WITH DEFAULT KEY,
changing TYPE STANDARD TABLE OF rscha WITH DEFAULT KEY,
export TYPE STANDARD TABLE OF rsexp WITH DEFAULT KEY,
tables TYPE STANDARD TABLE OF rstbl WITH DEFAULT KEY,
exception TYPE STANDARD TABLE OF rsexc WITH DEFAULT KEY,
documentation TYPE STANDARD TABLE OF rsfdo WITH DEFAULT KEY,
exception_classes TYPE abap_bool,
END OF ty_function .
TYPES:
ty_function_tt TYPE STANDARD TABLE OF ty_function WITH DEFAULT KEY .
METHODS update_where_used
IMPORTING
!it_includes TYPE rso_t_objnm .
METHODS main_name
RETURNING
VALUE(rv_program) TYPE program
RAISING
zcx_abapgit_exception .
METHODS functions
RETURNING
VALUE(rt_functab) TYPE ty_rs38l_incl_tt
RAISING
zcx_abapgit_exception .
METHODS includes
RETURNING
VALUE(rt_includes) TYPE rso_t_objnm
RAISING
zcx_abapgit_exception .
METHODS serialize_functions
RETURNING
VALUE(rt_functions) TYPE ty_function_tt
RAISING
zcx_abapgit_exception .
METHODS deserialize_functions
IMPORTING
!it_functions TYPE ty_function_tt
RAISING
zcx_abapgit_exception .
METHODS serialize_xml
IMPORTING
!io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING
zcx_abapgit_exception .
METHODS deserialize_xml
IMPORTING
!io_xml TYPE REF TO zcl_abapgit_xml_input
!iv_package TYPE devclass
RAISING
zcx_abapgit_exception .
METHODS serialize_includes
RAISING
zcx_abapgit_exception .
METHODS deserialize_includes
IMPORTING
!io_xml TYPE REF TO zcl_abapgit_xml_input
!iv_package TYPE devclass
RAISING
zcx_abapgit_exception .
METHODS are_exceptions_class_based
IMPORTING
!iv_function_name TYPE rs38l_fnam
RETURNING
VALUE(rv_return) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS is_function_group_locked
RETURNING
VALUE(rv_is_functions_group_locked) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS is_any_include_locked
RETURNING
VALUE(rv_is_any_include_locked) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS is_any_function_module_locked
RETURNING
VALUE(rv_any_function_module_locked) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS get_abap_version
IMPORTING
io_xml TYPE REF TO zcl_abapgit_xml_input
RETURNING
VALUE(rv_abap_version) TYPE progdir-uccheck
RAISING
zcx_abapgit_exception .
METHODS update_func_group_short_text
IMPORTING
iv_group TYPE rs38l-area
iv_short_text TYPE tftit-stext.
ENDCLASS.
CLASS zcl_abapgit_object_intf DEFINITION FINAL INHERITING FROM zcl_abapgit_objects_program.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
METHODS constructor
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras.
PROTECTED SECTION.
METHODS deserialize_abap
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
iv_package TYPE devclass
RAISING zcx_abapgit_exception.
METHODS deserialize_docu
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
DATA mi_object_oriented_object_fct TYPE REF TO zif_abapgit_oo_object_fnc.
METHODS serialize_xml
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_object_prog DEFINITION INHERITING FROM zcl_abapgit_objects_program FINAL.
PUBLIC SECTION.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
TYPES: BEGIN OF ty_tpool_i18n,
language TYPE langu,
textpool TYPE zif_abapgit_definitions=>ty_tpool_tt,
END OF ty_tpool_i18n,
tt_tpool_i18n TYPE STANDARD TABLE OF ty_tpool_i18n.
METHODS:
serialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_output
RAISING zcx_abapgit_exception,
deserialize_texts
IMPORTING io_xml TYPE REF TO zcl_abapgit_xml_input
RAISING zcx_abapgit_exception,
is_program_locked
RETURNING
VALUE(rv_is_program_locked) TYPE abap_bool
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_objects_saxx_super DEFINITION ABSTRACT
INHERITING FROM zcl_abapgit_objects_super.
PUBLIC SECTION.
INTERFACES:
zif_abapgit_object.
PROTECTED SECTION.
METHODS:
get_persistence_class_name ABSTRACT
RETURNING
VALUE(r_persistence_class_name) TYPE seoclsname,
get_data_class_name ABSTRACT
RETURNING
VALUE(r_data_class_name) TYPE seoclsname,
get_data_structure_name ABSTRACT
RETURNING
VALUE(r_data_structure_name) TYPE string.
PRIVATE SECTION.
DATA: mo_persistence TYPE REF TO if_wb_object_persist,
mo_appl_obj_data TYPE REF TO if_wb_object_data_model,
mv_data_structure_name TYPE string,
mv_appl_obj_cls_name TYPE seoclsname,
mv_persistence_cls_name TYPE seoclsname.
METHODS:
create_channel_objects
RAISING
zcx_abapgit_exception,
get_data
EXPORTING
p_data TYPE any
RAISING
zcx_abapgit_exception,
lock
RAISING
zcx_abapgit_exception,
unlock
RAISING
zcx_abapgit_exception,
get_names.
ENDCLASS.
CLASS zcl_abapgit_object_samc DEFINITION INHERITING FROM zcl_abapgit_objects_saxx_super FINAL.
PROTECTED SECTION.
METHODS:
get_persistence_class_name REDEFINITION,
get_data_class_name REDEFINITION,
get_data_structure_name REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_object_sapc DEFINITION INHERITING FROM zcl_abapgit_objects_saxx_super FINAL.
PROTECTED SECTION.
METHODS:
get_persistence_class_name REDEFINITION,
get_data_class_name REDEFINITION,
get_data_structure_name REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_oo_base DEFINITION ABSTRACT.
PUBLIC SECTION.
INTERFACES: zif_abapgit_oo_object_fnc.
PRIVATE SECTION.
DATA mv_skip_test_classes TYPE abap_bool.
METHODS deserialize_abap_source_old
IMPORTING is_clskey TYPE seoclskey
it_source TYPE zif_abapgit_definitions=>ty_string_tt
RAISING zcx_abapgit_exception.
METHODS deserialize_abap_source_new
IMPORTING is_clskey TYPE seoclskey
it_source TYPE zif_abapgit_definitions=>ty_string_tt
RAISING zcx_abapgit_exception
cx_sy_dyn_call_error.
ENDCLASS.
CLASS zcl_abapgit_oo_class DEFINITION INHERITING FROM zcl_abapgit_oo_base.
PUBLIC SECTION.
METHODS:
zif_abapgit_oo_object_fnc~create REDEFINITION,
zif_abapgit_oo_object_fnc~generate_locals REDEFINITION,
zif_abapgit_oo_object_fnc~insert_text_pool REDEFINITION,
zif_abapgit_oo_object_fnc~create_sotr REDEFINITION,
zif_abapgit_oo_object_fnc~get_includes REDEFINITION,
zif_abapgit_oo_object_fnc~get_class_properties REDEFINITION,
zif_abapgit_oo_object_fnc~read_text_pool REDEFINITION,
zif_abapgit_oo_object_fnc~read_sotr REDEFINITION,
zif_abapgit_oo_object_fnc~delete REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_oo_class_new DEFINITION INHERITING FROM zcl_abapgit_oo_class.
PUBLIC SECTION.
METHODS:
zif_abapgit_oo_object_fnc~create REDEFINITION,
zif_abapgit_oo_object_fnc~generate_locals REDEFINITION,
zif_abapgit_oo_object_fnc~deserialize_source REDEFINITION.
PRIVATE SECTION.
CLASS-METHODS update_source_index
IMPORTING
!iv_clsname TYPE csequence
!io_scanner TYPE REF TO cl_oo_source_scanner_class .
CLASS-METHODS update_report
IMPORTING
!iv_program TYPE programm
!it_source TYPE string_table
RETURNING
VALUE(rv_updated) TYPE abap_bool
RAISING
zcx_abapgit_exception .
CLASS-METHODS generate_classpool
IMPORTING
!iv_name TYPE seoclsname
RAISING
zcx_abapgit_exception .
CLASS-METHODS update_meta
IMPORTING
!iv_name TYPE seoclsname
!iv_exposure TYPE seoexpose
!it_source TYPE rswsourcet
RAISING
zcx_abapgit_exception .
CLASS-METHODS determine_method_include
IMPORTING
!iv_name TYPE seoclsname
!iv_method TYPE seocpdname
RETURNING
VALUE(rv_program) TYPE programm
RAISING
zcx_abapgit_exception .
CLASS-METHODS init_scanner
IMPORTING
!it_source TYPE zif_abapgit_definitions=>ty_string_tt
!iv_name TYPE seoclsname
RETURNING
VALUE(ro_scanner) TYPE REF TO cl_oo_source_scanner_class
RAISING
zcx_abapgit_exception .
CLASS-METHODS update_full_class_include
IMPORTING
!iv_classname TYPE seoclsname
!it_source TYPE string_table
!it_methods TYPE cl_oo_source_scanner_class=>type_method_implementations .
CLASS-METHODS create_report
IMPORTING
!iv_program TYPE programm
!it_source TYPE string_table
!iv_extension TYPE sychar02
!iv_program_type TYPE sychar01
!iv_version TYPE r3state .
CLASS-METHODS update_cs_number_of_methods
IMPORTING
!iv_classname TYPE seoclsname
!iv_number_of_impl_methods TYPE i .
ENDCLASS.
CLASS zcl_abapgit_oo_factory DEFINITION.
PUBLIC SECTION.
CLASS-METHODS:
make
IMPORTING
iv_object_type TYPE tadir-object
RETURNING
VALUE(ro_object_oriented_object) TYPE REF TO zif_abapgit_oo_object_fnc.
PRIVATE SECTION.
CLASS-DATA gi_object_oriented_object TYPE REF TO zif_abapgit_oo_object_fnc .
ENDCLASS.
CLASS zcl_abapgit_oo_interface DEFINITION
INHERITING FROM zcl_abapgit_oo_base.
PUBLIC SECTION.
METHODS:
zif_abapgit_oo_object_fnc~create REDEFINITION,
zif_abapgit_oo_object_fnc~get_includes REDEFINITION,
zif_abapgit_oo_object_fnc~get_interface_properties REDEFINITION,
zif_abapgit_oo_object_fnc~delete REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_oo_serializer DEFINITION CREATE PUBLIC.
PUBLIC SECTION.
METHODS serialize_abap_clif_source
IMPORTING
!is_class_key TYPE seoclskey
RETURNING
VALUE(rt_source) TYPE zif_abapgit_definitions=>ty_string_tt
RAISING
zcx_abapgit_exception
cx_sy_dyn_call_error .
METHODS are_test_classes_skipped
RETURNING
VALUE(rv_return) TYPE abap_bool .
METHODS serialize_locals_imp
IMPORTING
!is_clskey TYPE seoclskey
RETURNING
VALUE(rt_source) TYPE zif_abapgit_definitions=>ty_string_tt
RAISING
zcx_abapgit_exception .
METHODS serialize_locals_def
IMPORTING
!is_clskey TYPE seoclskey
RETURNING
VALUE(rt_source) TYPE zif_abapgit_definitions=>ty_string_tt
RAISING
zcx_abapgit_exception .
METHODS serialize_testclasses
IMPORTING
!is_clskey TYPE seoclskey
RETURNING
VALUE(rt_source) TYPE zif_abapgit_definitions=>ty_string_tt
RAISING
zcx_abapgit_exception .
METHODS serialize_macros
IMPORTING
!is_clskey TYPE seoclskey
RETURNING
VALUE(rt_source) TYPE zif_abapgit_definitions=>ty_string_tt
RAISING
zcx_abapgit_exception .
METHODS calculate_skip_testclass
IMPORTING
!it_source TYPE zif_abapgit_definitions=>ty_string_tt
RETURNING
VALUE(rv_skip_testclass) TYPE abap_bool .
PRIVATE SECTION.
DATA mv_skip_testclass TYPE abap_bool.
METHODS serialize_abap_old
IMPORTING is_clskey TYPE seoclskey
RETURNING VALUE(rt_source) TYPE zif_abapgit_definitions=>ty_string_tt
RAISING zcx_abapgit_exception.
METHODS serialize_abap_new
IMPORTING is_clskey TYPE seoclskey
RETURNING VALUE(rt_source) TYPE zif_abapgit_definitions=>ty_string_tt
RAISING zcx_abapgit_exception
cx_sy_dyn_call_error.
METHODS remove_signatures
CHANGING ct_source TYPE zif_abapgit_definitions=>ty_string_tt.
METHODS read_include
IMPORTING is_clskey TYPE seoclskey
iv_type TYPE seop_include_ext_app
RETURNING VALUE(rt_source) TYPE seop_source_string.
METHODS reduce
CHANGING ct_source TYPE zif_abapgit_definitions=>ty_string_tt.
ENDCLASS.
CLASS zcl_abapgit_persist_background DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: BEGIN OF ty_xml,
method TYPE string,
username TYPE string,
password TYPE string,
settings TYPE zif_abapgit_background=>ty_settings_tt,
END OF ty_xml.
TYPES: BEGIN OF ty_background,
key TYPE zif_abapgit_persistence=>ty_value.
INCLUDE TYPE ty_xml.
TYPES: END OF ty_background.
TYPES: tt_background TYPE STANDARD TABLE OF ty_background WITH DEFAULT KEY.
METHODS constructor.
METHODS list
RETURNING VALUE(rt_list) TYPE tt_background
RAISING zcx_abapgit_exception.
METHODS modify
IMPORTING is_data TYPE ty_background
RAISING zcx_abapgit_exception.
METHODS delete
IMPORTING iv_key TYPE ty_background-key
RAISING zcx_abapgit_exception.
METHODS exists
IMPORTING iv_key TYPE ty_background-key
RETURNING VALUE(rv_yes) TYPE abap_bool
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
DATA: mo_db TYPE REF TO zcl_abapgit_persistence_db,
mt_jobs TYPE tt_background.
METHODS from_xml
IMPORTING iv_string TYPE string
RETURNING VALUE(rs_xml) TYPE ty_xml
RAISING zcx_abapgit_exception.
METHODS to_xml
IMPORTING is_background TYPE ty_background
RETURNING VALUE(rv_string) TYPE string.
ENDCLASS.
CLASS zcl_abapgit_persist_factory DEFINITION
CREATE PRIVATE
FRIENDS ZCL_ABAPGIT_persist_injector .
PUBLIC SECTION.
CLASS-METHODS get_repo
RETURNING
VALUE(ri_repo) TYPE REF TO zif_abapgit_persist_repo .
PROTECTED SECTION.
PRIVATE SECTION.
CLASS-DATA gi_repo TYPE REF TO zif_abapgit_persist_repo .
ENDCLASS.
CLASS zcl_abapgit_persist_injector DEFINITION
CREATE PRIVATE
FOR TESTING .
PUBLIC SECTION.
CLASS-METHODS set_repo
IMPORTING
!ii_repo TYPE REF TO zif_abapgit_persist_repo .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_persist_migrate DEFINITION CREATE PUBLIC.
PUBLIC SECTION.
CLASS-METHODS: run RAISING zcx_abapgit_exception.
PRIVATE SECTION.
TYPES: BEGIN OF ty_settings_to_migrate,
name TYPE string,
value TYPE string,
END OF ty_settings_to_migrate,
tty_settings_to_migrate TYPE STANDARD TABLE OF ty_settings_to_migrate
WITH NON-UNIQUE DEFAULT KEY.
CONSTANTS c_text TYPE string VALUE 'Generated by abapGit' ##NO_TEXT.
CLASS-METHODS table_create
RAISING
zcx_abapgit_exception .
CLASS-METHODS table_exists
RETURNING
VALUE(rv_exists) TYPE abap_bool .
CLASS-METHODS lock_create
RAISING
zcx_abapgit_exception .
CLASS-METHODS lock_exists
RETURNING
VALUE(rv_exists) TYPE abap_bool .
CLASS-METHODS migrate_settings
RAISING
zcx_abapgit_exception.
CLASS-METHODS migrate_setting
IMPORTING
iv_name TYPE string
CHANGING
ct_settings_to_migrate TYPE tty_settings_to_migrate
ci_document TYPE REF TO if_ixml_document.
CLASS-METHODS distribute_settings_to_users
IMPORTING
it_settings_to_migrate TYPE tty_settings_to_migrate
RAISING
zcx_abapgit_exception.
CLASS-METHODS update_global_settings
IMPORTING
ii_document TYPE REF TO if_ixml_document
RAISING
zcx_abapgit_exception.
CLASS-METHODS read_global_settings_xml
RETURNING
VALUE(rv_global_settings_xml) TYPE string
RAISING
zcx_abapgit_not_found.
CLASS-METHODS get_global_settings_document
RETURNING
VALUE(ri_global_settings_dom) TYPE REF TO if_ixml_document
RAISING
zcx_abapgit_not_found.
ENDCLASS.
CLASS zcl_abapgit_persist_settings DEFINITION
CREATE PRIVATE .
PUBLIC SECTION.
METHODS modify
IMPORTING
!io_settings TYPE REF TO zcl_abapgit_settings
RAISING
zcx_abapgit_exception .
METHODS read
RETURNING
VALUE(ro_settings) TYPE REF TO zcl_abapgit_settings .
CLASS-METHODS get_instance
RETURNING
VALUE(ro_settings) TYPE REF TO zcl_abapgit_persist_settings .
PRIVATE SECTION.
DATA mo_settings TYPE REF TO zcl_abapgit_settings .
CLASS-DATA go_persist TYPE REF TO zcl_abapgit_persist_settings .
ENDCLASS.
CLASS zcl_abapgit_persistence_db DEFINITION
CREATE PRIVATE .
PUBLIC SECTION.
CONSTANTS c_tabname TYPE tabname VALUE 'ZABAPGIT' ##NO_TEXT.
CONSTANTS c_lock TYPE viewname VALUE 'EZABAPGIT' ##NO_TEXT.
CONSTANTS:
c_type_settings TYPE zif_abapgit_persistence=>ty_type VALUE 'SETTINGS' ##NO_TEXT,
c_type_repo TYPE zif_abapgit_persistence=>ty_type VALUE 'REPO' ##NO_TEXT,
c_type_background TYPE zif_abapgit_persistence=>ty_type VALUE 'BACKGROUND' ##NO_TEXT,
c_type_user TYPE zif_abapgit_persistence=>ty_type VALUE 'USER' ##NO_TEXT.
CLASS-METHODS get_instance
RETURNING
VALUE(ro_db) TYPE REF TO zcl_abapgit_persistence_db .
METHODS add
IMPORTING
!iv_type TYPE zif_abapgit_persistence=>ty_type
!iv_value TYPE zif_abapgit_persistence=>ty_content-value
!iv_data TYPE zif_abapgit_persistence=>ty_content-data_str
RAISING
zcx_abapgit_exception .
METHODS delete
IMPORTING
!iv_type TYPE zif_abapgit_persistence=>ty_type
!iv_value TYPE zif_abapgit_persistence=>ty_content-value
RAISING
zcx_abapgit_exception .
METHODS list
RETURNING
VALUE(rt_content) TYPE zif_abapgit_persistence=>tt_content .
METHODS list_by_type
IMPORTING
!iv_type TYPE zif_abapgit_persistence=>ty_type
RETURNING
VALUE(rt_content) TYPE zif_abapgit_persistence=>tt_content .
METHODS lock
IMPORTING
!iv_mode TYPE enqmode DEFAULT 'E'
!iv_type TYPE zif_abapgit_persistence=>ty_type
!iv_value TYPE zif_abapgit_persistence=>ty_content-value
RAISING
zcx_abapgit_exception .
METHODS modify
IMPORTING
!iv_type TYPE zif_abapgit_persistence=>ty_type
!iv_value TYPE zif_abapgit_persistence=>ty_content-value
!iv_data TYPE zif_abapgit_persistence=>ty_content-data_str
RAISING
zcx_abapgit_exception .
METHODS read
IMPORTING
!iv_type TYPE zif_abapgit_persistence=>ty_type
!iv_value TYPE zif_abapgit_persistence=>ty_content-value
RETURNING
VALUE(rv_data) TYPE zif_abapgit_persistence=>ty_content-data_str
RAISING
zcx_abapgit_not_found .
METHODS update
IMPORTING
!iv_type TYPE zif_abapgit_persistence=>ty_type
!iv_value TYPE zif_abapgit_persistence=>ty_content-value
!iv_data TYPE zif_abapgit_persistence=>ty_content-data_str
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
CLASS-DATA go_db TYPE REF TO zcl_abapgit_persistence_db .
METHODS validate_and_unprettify_xml
IMPORTING
!iv_xml TYPE string
RETURNING
VALUE(rv_xml) TYPE string
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_persistence_repo DEFINITION
CREATE PROTECTED
FRIENDS ZCL_ABAPGIT_persist_factory .
PUBLIC SECTION.
INTERFACES zif_abapgit_persist_repo .
METHODS constructor .
PROTECTED SECTION.
ALIASES list
FOR zif_abapgit_persist_repo~list .
ALIASES read
FOR zif_abapgit_persist_repo~read .
PRIVATE SECTION.
DATA mo_db TYPE REF TO zcl_abapgit_persistence_db .
METHODS from_xml
IMPORTING
!iv_repo_xml_string TYPE string
RETURNING
VALUE(rs_repo) TYPE zif_abapgit_persistence=>ty_repo_xml
RAISING
zcx_abapgit_exception .
METHODS to_xml
IMPORTING
!is_repo TYPE zif_abapgit_persistence=>ty_repo
RETURNING
VALUE(rv_repo_xml_string) TYPE string .
METHODS get_next_id
RETURNING
VALUE(rv_next_repo_id) TYPE zif_abapgit_persistence=>ty_content-value
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_persistence_user DEFINITION
CREATE PRIVATE .
PUBLIC SECTION.
INTERFACES zif_abapgit_persist_user .
TYPES tt_favorites TYPE zif_abapgit_persistence=>tt_repo_keys .
CLASS-METHODS get_instance
IMPORTING
!iv_user TYPE xubname DEFAULT sy-uname
RETURNING
VALUE(ri_user) TYPE REF TO zif_abapgit_persist_user .
PRIVATE SECTION.
TYPES:
BEGIN OF ty_repo_config,
url TYPE zif_abapgit_persistence=>ty_repo-url,
login TYPE string,
git_user TYPE zif_abapgit_definitions=>ty_git_user,
last_change_seen TYPE string,
END OF ty_repo_config .
TYPES:
ty_repo_config_tt TYPE STANDARD TABLE OF ty_repo_config WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_user,
default_git_user TYPE zif_abapgit_definitions=>ty_git_user,
repo_show TYPE zif_abapgit_persistence=>ty_repo-key,
hide_files TYPE abap_bool,
changes_only TYPE abap_bool,
diff_unified TYPE abap_bool,
favorites TYPE tt_favorites,
repo_config TYPE ty_repo_config_tt,
settings TYPE zif_abapgit_definitions=>ty_s_user_settings,
END OF ty_user .
DATA mv_user TYPE xubname .
CLASS-DATA gi_current_user TYPE REF TO zif_abapgit_persist_user .
METHODS constructor
IMPORTING
!iv_user TYPE xubname DEFAULT sy-uname .
METHODS from_xml
IMPORTING
!iv_xml TYPE string
RETURNING
VALUE(rs_user) TYPE ty_user
RAISING
zcx_abapgit_exception .
METHODS read
RETURNING
VALUE(rs_user) TYPE ty_user
RAISING
zcx_abapgit_exception .
METHODS read_repo_config
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
RETURNING
VALUE(rs_repo_config) TYPE ty_repo_config
RAISING
zcx_abapgit_exception .
METHODS to_xml
IMPORTING
!is_user TYPE ty_user
RETURNING
VALUE(rv_xml) TYPE string .
METHODS update
IMPORTING
!is_user TYPE ty_user
RAISING
zcx_abapgit_exception .
METHODS update_repo_config
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
!is_repo_config TYPE ty_repo_config
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_syntax_highlighter DEFINITION
ABSTRACT
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS create
IMPORTING
!iv_filename TYPE string
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_abapgit_syntax_highlighter .
METHODS process_line
IMPORTING
!iv_line TYPE string
RETURNING
VALUE(rv_line) TYPE string .
PROTECTED SECTION.
TYPES:
BEGIN OF ty_match,
token TYPE char1, " Type of matches
offset TYPE i, " Beginning position of the string that should be formatted
length TYPE i, " Length of the string that should be formatted
text_tag TYPE string, " Type of text tag
END OF ty_match.
TYPES:
ty_match_tt TYPE STANDARD TABLE OF ty_match WITH DEFAULT KEY.
TYPES:
BEGIN OF ty_rule,
regex TYPE REF TO cl_abap_regex,
token TYPE char1,
style TYPE string,
END OF ty_rule.
CONSTANTS c_token_none TYPE c VALUE '.'.
DATA mt_rules TYPE STANDARD TABLE OF ty_rule.
METHODS add_rule
IMPORTING
iv_regex TYPE string
iv_token TYPE c
iv_style TYPE string.
METHODS parse_line
IMPORTING iv_line TYPE string
EXPORTING et_matches TYPE ty_match_tt.
METHODS order_matches ABSTRACT
IMPORTING iv_line TYPE string
CHANGING ct_matches TYPE ty_match_tt.
METHODS extend_matches
IMPORTING iv_line TYPE string
CHANGING ct_matches TYPE ty_match_tt.
METHODS format_line
IMPORTING iv_line TYPE string
it_matches TYPE ty_match_tt
RETURNING VALUE(rv_line) TYPE string.
METHODS apply_style
IMPORTING iv_line TYPE string
iv_class TYPE string
RETURNING VALUE(rv_line) TYPE string.
ENDCLASS.
CLASS zcl_abapgit_syntax_abap DEFINITION
INHERITING FROM zcl_abapgit_syntax_highlighter
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS class_constructor.
METHODS constructor.
CONSTANTS:
BEGIN OF c_css,
keyword TYPE string VALUE 'keyword', "#EC NOTEXT
text TYPE string VALUE 'text', "#EC NOTEXT
comment TYPE string VALUE 'comment', "#EC NOTEXT
END OF c_css,
BEGIN OF c_token,
keyword TYPE c VALUE 'K', "#EC NOTEXT
text TYPE c VALUE 'T', "#EC NOTEXT
comment TYPE c VALUE 'C', "#EC NOTEXT
END OF c_token,
BEGIN OF c_regex,
comment TYPE string VALUE '##|"|^\*',
text TYPE string VALUE '`|''|\||\{|\}',
keyword TYPE string VALUE '&&|\b[-_a-z0-9]+\b',
END OF c_regex.
PROTECTED SECTION.
CLASS-DATA gt_keywords TYPE HASHED TABLE OF string WITH UNIQUE KEY table_line.
CLASS-METHODS init_keywords.
CLASS-METHODS is_keyword
IMPORTING iv_chunk TYPE string
RETURNING VALUE(rv_yes) TYPE abap_bool.
METHODS order_matches REDEFINITION.
METHODS parse_line REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_syntax_xml DEFINITION
INHERITING FROM zcl_abapgit_syntax_highlighter
CREATE PUBLIC .
PUBLIC SECTION.
CONSTANTS:
BEGIN OF c_css,
xml_tag TYPE string VALUE 'xml_tag', "#EC NOTEXT
attr TYPE string VALUE 'attr', "#EC NOTEXT
attr_val TYPE string VALUE 'attr_val', "#EC NOTEXT
END OF c_css .
CONSTANTS:
BEGIN OF c_token,
xml_tag TYPE c VALUE 'X', "#EC NOTEXT
attr TYPE c VALUE 'A', "#EC NOTEXT
attr_val TYPE c VALUE 'V', "#EC NOTEXT
END OF c_token .
CONSTANTS:
BEGIN OF c_regex,
xml_tag TYPE string VALUE '[<>]', "#EC NOTEXT
attr TYPE string VALUE '\s[-a-z:_0-9]+\s*(?==)', "#EC NOTEXT
attr_val TYPE string VALUE '["''][^''"]*[''"]', "#EC NOTEXT
END OF c_regex .
METHODS constructor .
PROTECTED SECTION.
METHODS order_matches REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_test_serialize DEFINITION
CREATE PUBLIC
FOR TESTING .
PUBLIC SECTION.
CLASS-METHODS check
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
RAISING
zcx_abapgit_exception .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_gui DEFINITION
FINAL
CREATE PRIVATE .
PUBLIC SECTION.
CLASS-METHODS: get_instance
RETURNING VALUE(ro_gui) TYPE REF TO zcl_abapgit_gui
RAISING zcx_abapgit_exception.
METHODS go_home
RAISING zcx_abapgit_exception.
METHODS back
IMPORTING iv_to_bookmark TYPE abap_bool DEFAULT abap_false
RETURNING VALUE(rv_exit) TYPE xfeld
RAISING zcx_abapgit_exception.
METHODS on_event FOR EVENT sapevent OF cl_gui_html_viewer
IMPORTING action frame getdata postdata query_table. "#EC NEEDED
METHODS focus.
PRIVATE SECTION.
CLASS-DATA: go_gui TYPE REF TO zcl_abapgit_gui.
TYPES: BEGIN OF ty_page_stack,
page TYPE REF TO zif_abapgit_gui_page,
bookmark TYPE abap_bool,
END OF ty_page_stack.
DATA: mi_cur_page TYPE REF TO zif_abapgit_gui_page,
mt_stack TYPE STANDARD TABLE OF ty_page_stack,
mo_router TYPE REF TO zcl_abapgit_gui_router,
mo_asset_man TYPE REF TO zcl_abapgit_gui_asset_manager,
mo_html_viewer TYPE REF TO cl_gui_html_viewer.
METHODS constructor
RAISING zcx_abapgit_exception.
METHODS startup
RAISING zcx_abapgit_exception.
METHODS cache_html
IMPORTING iv_text TYPE string
RETURNING VALUE(rv_url) TYPE w3url.
METHODS cache_asset
IMPORTING iv_text TYPE string OPTIONAL
iv_xdata TYPE xstring OPTIONAL
iv_url TYPE w3url OPTIONAL
iv_type TYPE c
iv_subtype TYPE c
RETURNING VALUE(rv_url) TYPE w3url.
METHODS render
RAISING zcx_abapgit_exception.
METHODS get_current_page_name
RETURNING VALUE(rv_page_name) TYPE string.
METHODS call_page
IMPORTING ii_page TYPE REF TO zif_abapgit_gui_page
iv_with_bookmark TYPE abap_bool DEFAULT abap_false
iv_replacing TYPE abap_bool DEFAULT abap_false
RAISING zcx_abapgit_exception.
METHODS handle_action
IMPORTING iv_action TYPE c
iv_frame TYPE c OPTIONAL
iv_getdata TYPE c OPTIONAL
it_postdata TYPE cnht_post_data_tab OPTIONAL
it_query_table TYPE cnht_query_table OPTIONAL.
ENDCLASS.
CLASS zcl_abapgit_gui_asset_manager DEFINITION FINAL CREATE PUBLIC .
PUBLIC SECTION.
METHODS get_asset
IMPORTING iv_asset_name TYPE string
RETURNING VALUE(rv_data) TYPE xstring
RAISING zcx_abapgit_exception.
METHODS get_images
RETURNING VALUE(rt_images) TYPE zif_abapgit_definitions=>tt_web_assets.
CLASS-METHODS get_webfont_link
RETURNING VALUE(rv_link) TYPE string.
PRIVATE SECTION.
METHODS get_inline_asset
IMPORTING iv_asset_name TYPE string
RETURNING VALUE(rv_data) TYPE xstring
RAISING zcx_abapgit_exception.
METHODS get_mime_asset
IMPORTING iv_asset_name TYPE c
RETURNING VALUE(rv_data) TYPE xstring
RAISING zcx_abapgit_exception.
METHODS get_inline_images
RETURNING VALUE(rt_images) TYPE zif_abapgit_definitions=>tt_web_assets.
ENDCLASS.
CLASS zcl_abapgit_gui_chunk_lib DEFINITION FINAL CREATE PUBLIC.
PUBLIC SECTION.
CLASS-METHODS render_error
IMPORTING ix_error TYPE REF TO zcx_abapgit_exception OPTIONAL
iv_error TYPE string OPTIONAL
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
CLASS-METHODS render_repo_top
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo
iv_show_package TYPE abap_bool DEFAULT abap_true
iv_show_branch TYPE abap_bool DEFAULT abap_true
iv_interactive_branch TYPE abap_bool DEFAULT abap_false
iv_branch TYPE string OPTIONAL
io_news TYPE REF TO zcl_abapgit_news OPTIONAL
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
CLASS-METHODS render_item_state
IMPORTING iv_lstate TYPE char1
iv_rstate TYPE char1
RETURNING VALUE(rv_html) TYPE string.
CLASS-METHODS render_branch_span
IMPORTING iv_branch TYPE string
io_repo TYPE REF TO zcl_abapgit_repo_online
iv_interactive TYPE abap_bool
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
CLASS-METHODS render_js_error_banner
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
CLASS-METHODS render_news
IMPORTING
io_news TYPE REF TO zcl_abapgit_news
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
CLASS-METHODS render_hotkey_overview
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_gui_page DEFINITION ABSTRACT CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES:
zif_abapgit_gui_page.
CONSTANTS:
BEGIN OF c_global_page_action,
showhotkeys TYPE string VALUE `showHotkeys` ##NO_TEXT,
END OF c_global_page_action.
CLASS-METHODS:
get_hotkey_actions
RETURNING
VALUE(rt_hotkey_actions) TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action.
PROTECTED SECTION.
TYPES: BEGIN OF ty_control,
redirect_url TYPE string,
page_title TYPE string,
page_menu TYPE REF TO zcl_abapgit_html_toolbar,
END OF ty_control.
DATA: ms_control TYPE ty_control.
METHODS render_content ABSTRACT
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
METHODS scripts
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
METHODS html_head
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS title
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS footer
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS redirect
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS link_hints
IMPORTING
io_html TYPE REF TO zcl_abapgit_html
RAISING
zcx_abapgit_exception.
METHODS add_hotkeys
IMPORTING
io_html TYPE REF TO zcl_abapgit_html
RAISING
zcx_abapgit_exception.
METHODS render_hotkey_overview
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_gui_page_db DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS constructor .
METHODS zif_abapgit_gui_page~on_event
REDEFINITION .
PROTECTED SECTION.
METHODS render_content
REDEFINITION .
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_action,
delete TYPE string VALUE 'delete',
END OF c_action .
CLASS-METHODS delete
IMPORTING
!is_key TYPE zif_abapgit_persistence=>ty_content
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
METHODS explain_content
IMPORTING
!is_data TYPE zif_abapgit_persistence=>ty_content
RETURNING
VALUE(rv_text) TYPE string
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_gui_page_db_dis DEFINITION
FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS: constructor
IMPORTING is_key TYPE zif_abapgit_persistence=>ty_content.
CLASS-METHODS: render_record_banner
IMPORTING is_key TYPE zif_abapgit_persistence=>ty_content
RETURNING VALUE(rv_html) TYPE string.
PROTECTED SECTION.
METHODS render_content REDEFINITION.
PRIVATE SECTION.
DATA: ms_key TYPE zif_abapgit_persistence=>ty_content.
ENDCLASS.
CLASS zcl_abapgit_gui_page_db_edit DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS constructor
IMPORTING
is_key TYPE zif_abapgit_persistence=>ty_content .
METHODS zif_abapgit_gui_page~on_event
REDEFINITION .
PROTECTED SECTION.
CLASS-METHODS dbcontent_decode
IMPORTING
!it_postdata TYPE cnht_post_data_tab
RETURNING
VALUE(rs_content) TYPE zif_abapgit_persistence=>ty_content .
METHODS render_content
REDEFINITION .
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_action,
update TYPE string VALUE 'update',
END OF c_action .
DATA ms_key TYPE zif_abapgit_persistence=>ty_content .
CLASS-METHODS update
IMPORTING
!is_content TYPE zif_abapgit_persistence=>ty_content
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_gui_page_bkg DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS constructor
IMPORTING
iv_key TYPE zif_abapgit_persistence=>ty_repo-key .
METHODS zif_abapgit_gui_page~on_event
REDEFINITION .
PROTECTED SECTION.
METHODS read_persist
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
RETURNING
VALUE(rs_persist) TYPE zcl_abapgit_persist_background=>ty_background
RAISING
zcx_abapgit_exception .
METHODS render_methods
IMPORTING
!is_per TYPE zcl_abapgit_persist_background=>ty_background
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_settings
IMPORTING
!is_per TYPE zcl_abapgit_persist_background=>ty_background
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS build_menu
RETURNING
VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar .
CLASS-METHODS update
IMPORTING
!is_bg_task TYPE zcl_abapgit_persist_background=>ty_background
RAISING
zcx_abapgit_exception .
METHODS render
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING
zcx_abapgit_exception .
METHODS decode
IMPORTING
!iv_getdata TYPE clike
RETURNING
VALUE(rs_fields) TYPE zcl_abapgit_persist_background=>ty_background .
METHODS render_content
REDEFINITION .
PRIVATE SECTION.
DATA mv_key TYPE zif_abapgit_persistence=>ty_repo-key .
ENDCLASS.
CLASS zcl_abapgit_gui_page_bkg_run DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS constructor .
METHODS zif_abapgit_gui_page~on_event
REDEFINITION .
PROTECTED SECTION.
METHODS render_content REDEFINITION.
PRIVATE SECTION.
DATA: mt_text TYPE TABLE OF string.
METHODS: run.
ENDCLASS.
CLASS zcl_abapgit_gui_page_boverview DEFINITION
FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS:
constructor
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo_online
RAISING zcx_abapgit_exception,
zif_abapgit_gui_page~on_event REDEFINITION.
PROTECTED SECTION.
METHODS render_content REDEFINITION.
PRIVATE SECTION.
DATA: mo_repo TYPE REF TO zcl_abapgit_repo_online,
mv_compress TYPE abap_bool VALUE abap_false,
mt_commits TYPE zif_abapgit_definitions=>ty_commit_tt,
mi_branch_overview TYPE REF TO zif_abapgit_branch_overview.
CONSTANTS: BEGIN OF c_actions,
uncompress TYPE string VALUE 'uncompress' ##NO_TEXT,
compress TYPE string VALUE 'compress' ##NO_TEXT,
refresh TYPE string VALUE 'refresh' ##NO_TEXT,
merge TYPE string VALUE 'merge' ##NO_TEXT,
END OF c_actions.
TYPES: BEGIN OF ty_merge,
source TYPE string,
target TYPE string,
END OF ty_merge.
METHODS:
refresh
RAISING zcx_abapgit_exception,
body
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
form_select
IMPORTING iv_name TYPE string
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
render_merge
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
decode_merge
IMPORTING it_postdata TYPE cnht_post_data_tab
RETURNING VALUE(rs_merge) TYPE ty_merge
RAISING zcx_abapgit_exception,
build_menu
RETURNING VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar,
escape_branch
IMPORTING iv_string TYPE string
RETURNING VALUE(rv_string) TYPE string,
escape_message
IMPORTING iv_string TYPE string
RETURNING VALUE(rv_string) TYPE string.
ENDCLASS.
CLASS zcl_abapgit_gui_page_code_insp DEFINITION FINAL CREATE PUBLIC
INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS:
constructor
IMPORTING
io_repo TYPE REF TO zcl_abapgit_repo
io_stage TYPE REF TO zcl_abapgit_stage OPTIONAL
RAISING
zcx_abapgit_exception,
zif_abapgit_gui_page~on_event
REDEFINITION,
zif_abapgit_gui_page~render
REDEFINITION.
PROTECTED SECTION.
DATA: mo_repo TYPE REF TO zcl_abapgit_repo.
METHODS:
render_content REDEFINITION.
PRIVATE SECTION.
CONSTANTS:
BEGIN OF c_actions,
stage TYPE string VALUE 'stage' ##NO_TEXT,
commit TYPE string VALUE 'commit' ##NO_TEXT,
rerun TYPE string VALUE 'rerun' ##NO_TEXT,
END OF c_actions.
DATA:
mt_result TYPE scit_alvlist,
mo_stage TYPE REF TO zcl_abapgit_stage.
METHODS:
build_menu
RETURNING
VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar
RAISING
zcx_abapgit_exception,
run_code_inspector
RAISING
zcx_abapgit_exception,
has_inspection_errors
RETURNING
VALUE(rv_has_inspection_errors) TYPE abap_bool,
is_stage_allowed
RETURNING
VALUE(rv_is_stage_allowed) TYPE abap_bool,
jump
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_gui_page_commit DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
CONSTANTS:
BEGIN OF c_action,
commit_post TYPE string VALUE 'commit_post',
commit_cancel TYPE string VALUE 'commit_cancel',
END OF c_action .
METHODS constructor
IMPORTING
io_repo TYPE REF TO zcl_abapgit_repo_online
io_stage TYPE REF TO zcl_abapgit_stage
RAISING
zcx_abapgit_exception.
METHODS zif_abapgit_gui_page~on_event
REDEFINITION .
PROTECTED SECTION.
CLASS-METHODS parse_commit_request
IMPORTING
!it_postdata TYPE cnht_post_data_tab
EXPORTING
!eg_fields TYPE any .
METHODS render_content
REDEFINITION .
METHODS scripts
REDEFINITION .
PRIVATE SECTION.
DATA: mo_repo TYPE REF TO zcl_abapgit_repo_online,
mo_stage TYPE REF TO zcl_abapgit_stage.
METHODS:
render_menu
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
render_stage
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
render_form
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
render_text_input
IMPORTING iv_name TYPE string
iv_label TYPE string
iv_value TYPE string OPTIONAL
iv_max_length TYPE string OPTIONAL
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
ENDCLASS.
CLASS zcl_abapgit_gui_page_debuginfo DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS constructor .
PROTECTED SECTION.
METHODS:
render_content REDEFINITION,
scripts REDEFINITION.
PRIVATE SECTION.
METHODS render_debug_info
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
METHODS render_supported_object_types
RETURNING VALUE(rv_html) TYPE string.
ENDCLASS.
CLASS zcl_abapgit_gui_page_diff DEFINITION
FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
CONSTANTS:
BEGIN OF c_fstate,
local TYPE char1 VALUE 'L',
remote TYPE char1 VALUE 'R',
both TYPE char1 VALUE 'B',
END OF c_fstate.
TYPES: BEGIN OF ty_file_diff,
path TYPE string,
filename TYPE string,
lstate TYPE char1,
rstate TYPE char1,
fstate TYPE char1, " FILE state - Abstraction for shorter ifs
o_diff TYPE REF TO zcl_abapgit_diff,
changed_by TYPE xubname,
type TYPE string,
END OF ty_file_diff,
tt_file_diff TYPE STANDARD TABLE OF ty_file_diff.
METHODS:
constructor
IMPORTING iv_key TYPE zif_abapgit_persistence=>ty_repo-key
is_file TYPE zif_abapgit_definitions=>ty_file OPTIONAL
is_object TYPE zif_abapgit_definitions=>ty_item OPTIONAL
RAISING zcx_abapgit_exception,
zif_abapgit_gui_page~on_event REDEFINITION.
PROTECTED SECTION.
METHODS:
render_content REDEFINITION,
scripts REDEFINITION.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_actions,
toggle_unified TYPE string VALUE 'toggle_unified',
END OF c_actions.
DATA: mt_diff_files TYPE tt_file_diff,
mt_delayed_lines TYPE zif_abapgit_definitions=>ty_diffs_tt,
mv_unified TYPE abap_bool VALUE abap_true,
mv_repo_key TYPE zif_abapgit_persistence=>ty_repo-key,
mv_seed TYPE string. " Unique page id to bind JS sessionStorage
METHODS render_diff
IMPORTING is_diff TYPE ty_file_diff
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_diff_head
IMPORTING is_diff TYPE ty_file_diff
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_table_head
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_lines
IMPORTING is_diff TYPE ty_file_diff
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_beacon
IMPORTING is_diff_line TYPE zif_abapgit_definitions=>ty_diff
is_diff TYPE ty_file_diff
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_line_split
IMPORTING is_diff_line TYPE zif_abapgit_definitions=>ty_diff
iv_fstate TYPE char1
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_line_unified
IMPORTING is_diff_line TYPE zif_abapgit_definitions=>ty_diff OPTIONAL
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS append_diff
IMPORTING it_remote TYPE zif_abapgit_definitions=>ty_files_tt
it_local TYPE zif_abapgit_definitions=>ty_files_item_tt
is_status TYPE zif_abapgit_definitions=>ty_result
RAISING zcx_abapgit_exception.
METHODS build_menu
RETURNING VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar.
METHODS is_binary
IMPORTING iv_d1 TYPE xstring
iv_d2 TYPE xstring
RETURNING VALUE(rv_yes) TYPE abap_bool.
ENDCLASS.
CLASS zcl_abapgit_gui_page_explore DEFINITION
FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
CONSTANTS c_explore_url TYPE string
VALUE 'https://dotabap.github.io/explore.html'.
METHODS constructor.
PROTECTED SECTION.
METHODS render_content REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_gui_page_main DEFINITION
FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS:
constructor
RAISING zcx_abapgit_exception,
zif_abapgit_gui_page~on_event REDEFINITION.
PROTECTED SECTION.
METHODS:
render_content REDEFINITION.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_actions,
show TYPE string VALUE 'show' ##NO_TEXT,
changed_by TYPE string VALUE 'changed_by',
overview TYPE string VALUE 'overview',
documentation TYPE string VALUE 'documentation',
END OF c_actions.
DATA: mv_show TYPE zif_abapgit_persistence=>ty_value,
mo_repo_content TYPE REF TO zcl_abapgit_gui_view_repo.
METHODS:
test_changed_by
RAISING zcx_abapgit_exception,
retrieve_active_repo
RAISING zcx_abapgit_exception,
render_toc
IMPORTING it_repo_list TYPE zif_abapgit_definitions=>ty_repo_ref_tt
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
build_main_menu
RETURNING VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar,
render_repo
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_gui_page_merge DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS constructor
IMPORTING
io_repo TYPE REF TO zcl_abapgit_repo_online
iv_source TYPE string
iv_target TYPE string
RAISING
zcx_abapgit_exception .
METHODS zif_abapgit_gui_page~on_event
REDEFINITION.
PROTECTED SECTION.
METHODS render_content REDEFINITION.
PRIVATE SECTION.
DATA mo_repo TYPE REF TO zcl_abapgit_repo_online .
DATA mo_merge TYPE REF TO zcl_abapgit_merge .
CONSTANTS:
BEGIN OF c_actions,
merge TYPE string VALUE 'merge' ##NO_TEXT,
res_conflicts TYPE string VALUE 'res_conflicts' ##NO_TEXT,
END OF c_actions .
METHODS build_menu
IMPORTING
VALUE(iv_with_conflict) TYPE boolean OPTIONAL
RETURNING
VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar .
ENDCLASS.
CLASS zcl_abapgit_gui_page_merge_res DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS constructor
IMPORTING
io_repo TYPE REF TO zcl_abapgit_repo_online
io_merge_page TYPE REF TO zcl_abapgit_gui_page_merge
io_merge TYPE REF TO zcl_abapgit_merge
RAISING
zcx_abapgit_exception.
METHODS zif_abapgit_gui_page~on_event
REDEFINITION .
PROTECTED SECTION.
METHODS render_content REDEFINITION.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_file_diff,
path TYPE string,
filename TYPE string,
lstate TYPE char1,
rstate TYPE char1,
fstate TYPE char1, " FILE state - Abstraction for shorter ifs
o_diff TYPE REF TO zcl_abapgit_diff,
changed_by TYPE xubname,
type TYPE string,
END OF ty_file_diff .
CONSTANTS:
BEGIN OF c_actions,
toggle_mode TYPE string VALUE 'toggle_mode' ##NO_TEXT,
apply_merge TYPE string VALUE 'apply_merge' ##NO_TEXT,
apply_source TYPE string VALUE 'apply_source' ##NO_TEXT,
apply_target TYPE string VALUE 'apply_target' ##NO_TEXT,
cancel TYPE string VALUE 'cancel' ##NO_TEXT,
END OF c_actions .
CONSTANTS:
BEGIN OF c_merge_mode,
selection TYPE string VALUE 'selection' ##NO_TEXT,
merge TYPE string VALUE 'merge' ##NO_TEXT,
END OF c_merge_mode .
DATA mo_merge TYPE REF TO zcl_abapgit_merge .
DATA mo_merge_page TYPE REF TO zcl_abapgit_gui_page_merge .
DATA mo_repo TYPE REF TO zcl_abapgit_repo_online .
DATA ms_diff_file TYPE ty_file_diff .
DATA mv_current_conflict_index TYPE sytabix .
DATA mv_merge_mode TYPE string .
DATA mt_conflicts TYPE zif_abapgit_definitions=>tt_merge_conflict .
METHODS apply_merged_content
IMPORTING
!it_postdata TYPE cnht_post_data_tab
RAISING
zcx_abapgit_exception .
METHODS build_menu
IMPORTING
VALUE(iv_with_conflict) TYPE boolean OPTIONAL
RETURNING
VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar .
METHODS is_binary
IMPORTING
!iv_d1 TYPE xstring
!iv_d2 TYPE xstring
RETURNING
VALUE(rv_yes) TYPE abap_bool .
METHODS render_beacon
IMPORTING
!is_diff_line TYPE zif_abapgit_definitions=>ty_diff
!is_diff TYPE ty_file_diff
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_diff
IMPORTING
!is_diff TYPE ty_file_diff
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING
zcx_abapgit_exception .
METHODS render_diff_head
IMPORTING
!is_diff TYPE ty_file_diff
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_lines
IMPORTING
!is_diff TYPE ty_file_diff
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_line_split
IMPORTING
!is_diff_line TYPE zif_abapgit_definitions=>ty_diff
!iv_fstate TYPE char1
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_table_head
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS resolve_diff
RAISING
zcx_abapgit_exception .
METHODS toggle_merge_mode .
ENDCLASS.
CLASS zcl_abapgit_gui_page_repo_over DEFINITION
INHERITING FROM zcl_abapgit_gui_page
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS constructor .
METHODS zif_abapgit_gui_page~on_event
REDEFINITION .
PROTECTED SECTION.
METHODS:
render_content REDEFINITION,
scripts REDEFINITION.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_overview,
favorite TYPE string,
type TYPE string,
key TYPE string,
name TYPE string,
url TYPE string,
package TYPE string,
branch TYPE string,
created_by TYPE string,
created_at TYPE string,
deserialized_by TYPE string,
deserialized_at TYPE string,
END OF ty_overview,
tty_overview TYPE STANDARD TABLE OF ty_overview
WITH NON-UNIQUE DEFAULT KEY.
CONSTANTS:
BEGIN OF c_action,
delete TYPE string VALUE 'delete',
select TYPE string VALUE 'select',
change_order_by TYPE string VALUE 'change_order_by',
direction TYPE string VALUE 'direction',
apply_filter TYPE string VALUE 'apply_filter',
END OF c_action .
DATA:
mv_order_by TYPE string,
mv_order_descending TYPE char01,
mv_filter TYPE string,
mv_time_zone TYPE timezone.
METHODS:
render_text_input
IMPORTING iv_name TYPE string
iv_label TYPE string
iv_value TYPE string OPTIONAL
iv_max_length TYPE string OPTIONAL
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
parse_change_order_by
IMPORTING
it_postdata TYPE cnht_post_data_tab,
parse_direction
IMPORTING
it_postdata TYPE cnht_post_data_tab,
parse_filter
IMPORTING
it_postdata TYPE cnht_post_data_tab,
add_order_by_option
IMPORTING
iv_option TYPE string
io_html TYPE REF TO zcl_abapgit_html,
add_direction_option
IMPORTING
iv_option TYPE string
io_html TYPE REF TO zcl_abapgit_html
iv_selected TYPE abap_bool,
apply_order_by
CHANGING
ct_overview TYPE zcl_abapgit_gui_page_repo_over=>tty_overview,
apply_filter
CHANGING
ct_overview TYPE zcl_abapgit_gui_page_repo_over=>tty_overview,
map_repo_list_to_overview
IMPORTING
it_repo_list TYPE zif_abapgit_persistence=>tt_repo
RETURNING
VALUE(rt_overview) TYPE zcl_abapgit_gui_page_repo_over=>tty_overview
RAISING
zcx_abapgit_exception,
render_table_header
IMPORTING
io_html TYPE REF TO zcl_abapgit_html,
render_table
IMPORTING
io_html TYPE REF TO zcl_abapgit_html
it_overview TYPE zcl_abapgit_gui_page_repo_over=>tty_overview,
render_table_body
IMPORTING
io_html TYPE REF TO zcl_abapgit_html
it_overview TYPE zcl_abapgit_gui_page_repo_over=>tty_overview,
render_order_by
IMPORTING
io_html TYPE REF TO zcl_abapgit_html,
render_order_by_direction
IMPORTING
io_html TYPE REF TO zcl_abapgit_html,
render_header_bar
IMPORTING
io_html TYPE REF TO zcl_abapgit_html.
ENDCLASS.
CLASS zcl_abapgit_gui_page_repo_sett DEFINITION FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS:
constructor
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo,
zif_abapgit_gui_page~on_event REDEFINITION.
PROTECTED SECTION.
CONSTANTS:
BEGIN OF c_action,
save_settings TYPE string VALUE 'save_settings',
END OF c_action .
DATA mo_repo TYPE REF TO zcl_abapgit_repo.
METHODS render_dot_abapgit
IMPORTING
!io_html TYPE REF TO zcl_abapgit_html .
METHODS render_local_settings
IMPORTING
!io_html TYPE REF TO zcl_abapgit_html .
METHODS save
IMPORTING
!it_postdata TYPE cnht_post_data_tab
RAISING
zcx_abapgit_exception .
METHODS save_dot_abap
IMPORTING
!it_post_fields TYPE tihttpnvp
RAISING
zcx_abapgit_exception .
METHODS save_local_settings
IMPORTING
!it_post_fields TYPE tihttpnvp
RAISING
zcx_abapgit_exception .
METHODS parse_post
IMPORTING
!it_postdata TYPE cnht_post_data_tab
RETURNING
VALUE(rt_post_fields) TYPE tihttpnvp .
METHODS render_content
REDEFINITION .
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_gui_page_settings DEFINITION
FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
CONSTANTS:
BEGIN OF c_action,
save_settings TYPE string VALUE 'save_settings',
END OF c_action.
METHODS constructor.
METHODS zif_abapgit_gui_page~on_event REDEFINITION.
PROTECTED SECTION.
METHODS render_content REDEFINITION.
PRIVATE SECTION.
DATA:
mo_settings TYPE REF TO zcl_abapgit_settings,
mv_error TYPE abap_bool.
METHODS render_proxy
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_development_internals
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_form_begin
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_form_end
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_max_lines
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_adt_jump_enabled
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_commit_msg
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS build_settings
IMPORTING
it_post_fields TYPE tihttpnvp.
METHODS validate_settings.
METHODS parse_post
IMPORTING
it_postdata TYPE cnht_post_data_tab
RETURNING
VALUE(rt_post_fields) TYPE tihttpnvp.
METHODS persist_settings
RAISING
zcx_abapgit_exception.
METHODS read_settings.
METHODS render_section_begin
IMPORTING
iv_header TYPE csequence
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_section_end
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_start_up
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
METHODS render_link_hints
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING
zcx_abapgit_exception.
METHODS render_hotkeys
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING
zcx_abapgit_exception.
METHODS get_possible_hotkey_actions
RETURNING
VALUE(rt_hotkey_actions) TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action
RAISING
zcx_abapgit_exception.
METHODS get_default_hotkeys
RETURNING
VALUE(rt_default_hotkeys) TYPE zif_abapgit_definitions=>tty_hotkey
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_gui_page_stage DEFINITION
FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
CONSTANTS: BEGIN OF c_action,
stage_all TYPE string VALUE 'stage_all',
stage_commit TYPE string VALUE 'stage_commit',
END OF c_action.
METHODS:
constructor
IMPORTING
io_repo TYPE REF TO zcl_abapgit_repo_online
iv_seed TYPE string OPTIONAL
RAISING zcx_abapgit_exception,
zif_abapgit_gui_page~on_event REDEFINITION.
PROTECTED SECTION.
METHODS:
render_content REDEFINITION,
scripts REDEFINITION.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_changed_by,
item TYPE zif_abapgit_definitions=>ty_item,
name TYPE xubname,
END OF ty_changed_by .
TYPES:
ty_changed_by_tt TYPE SORTED TABLE OF ty_changed_by WITH UNIQUE KEY item.
DATA mo_repo TYPE REF TO zcl_abapgit_repo_online .
DATA ms_files TYPE zif_abapgit_definitions=>ty_stage_files .
DATA mv_seed TYPE string . " Unique page id to bind JS sessionStorage
METHODS find_changed_by
IMPORTING
!it_local TYPE zif_abapgit_definitions=>ty_files_item_tt
RETURNING
VALUE(rt_changed_by) TYPE ty_changed_by_tt .
METHODS render_list
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_file
IMPORTING
!iv_context TYPE string
!is_file TYPE zif_abapgit_definitions=>ty_file
!is_item TYPE zif_abapgit_definitions=>ty_item OPTIONAL
!iv_changed_by TYPE xubname OPTIONAL
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS render_actions
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS process_stage_list
IMPORTING
!it_postdata TYPE cnht_post_data_tab
!io_stage TYPE REF TO zcl_abapgit_stage
RAISING
zcx_abapgit_exception .
METHODS build_menu
RETURNING
VALUE(ro_menu) TYPE REF TO zcl_abapgit_html_toolbar .
ENDCLASS.
CLASS zcl_abapgit_gui_page_syntax DEFINITION FINAL CREATE PUBLIC
INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
METHODS:
constructor
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo.
PROTECTED SECTION.
DATA: mo_repo TYPE REF TO zcl_abapgit_repo.
METHODS:
render_content REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_gui_page_tag DEFINITION FINAL
CREATE PUBLIC INHERITING FROM zcl_abapgit_gui_page.
PUBLIC SECTION.
INTERFACES: zif_abapgit_gui_page_hotkey.
CONSTANTS: BEGIN OF c_action,
commit_post TYPE string VALUE 'commit_post',
commit_cancel TYPE string VALUE 'commit_cancel',
change_tag_type TYPE string VALUE 'change_tag_type',
END OF c_action.
METHODS:
constructor
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo
RAISING zcx_abapgit_exception,
zif_abapgit_gui_page~on_event REDEFINITION.
PROTECTED SECTION.
METHODS:
render_content REDEFINITION,
scripts REDEFINITION.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_tag_type,
lightweight TYPE string VALUE 'lightweight',
annotated TYPE string VALUE 'annotated',
END OF c_tag_type.
DATA: mo_repo_online TYPE REF TO zcl_abapgit_repo_online,
mv_selected_type TYPE string.
METHODS:
render_menu
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
render_form
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
render_text_input
IMPORTING iv_name TYPE string
iv_label TYPE string
iv_value TYPE string OPTIONAL
iv_max_length TYPE string OPTIONAL
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
create_tag
IMPORTING it_postdata TYPE cnht_post_data_tab
RAISING zcx_abapgit_exception,
parse_tag_request
IMPORTING it_postdata TYPE cnht_post_data_tab
EXPORTING eg_fields TYPE any,
parse_change_tag_type_request
IMPORTING
it_postdata TYPE cnht_post_data_tab.
ENDCLASS.
CLASS zcl_abapgit_gui_router DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS on_event
IMPORTING iv_action TYPE clike
iv_prev_page TYPE clike
iv_getdata TYPE clike OPTIONAL
it_postdata TYPE cnht_post_data_tab OPTIONAL
EXPORTING ei_page TYPE REF TO zif_abapgit_gui_page
ev_state TYPE i
RAISING zcx_abapgit_exception zcx_abapgit_cancel.
PRIVATE SECTION.
METHODS get_page_diff
IMPORTING iv_getdata TYPE clike
iv_prev_page TYPE clike
RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_page
RAISING zcx_abapgit_exception.
METHODS get_page_branch_overview
IMPORTING iv_getdata TYPE clike
RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_page
RAISING zcx_abapgit_exception.
METHODS get_page_stage
IMPORTING iv_getdata TYPE clike
RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_page
RAISING zcx_abapgit_exception.
METHODS get_page_background
IMPORTING iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_page
RAISING zcx_abapgit_exception.
METHODS get_page_playground
RETURNING VALUE(ri_page) TYPE REF TO zif_abapgit_gui_page
RAISING zcx_abapgit_exception zcx_abapgit_cancel.
ENDCLASS.
CLASS zcl_abapgit_gui_view_repo DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_gui_page .
INTERFACES zif_abapgit_gui_page_hotkey.
ALIASES render
FOR zif_abapgit_gui_page~render .
CONSTANTS:
BEGIN OF c_actions,
change_dir TYPE string VALUE 'change_dir' ##NO_TEXT,
toggle_hide_files TYPE string VALUE 'toggle_hide_files' ##NO_TEXT,
toggle_folders TYPE string VALUE 'toggle_folders' ##NO_TEXT,
toggle_changes TYPE string VALUE 'toggle_changes' ##NO_TEXT,
display_more TYPE string VALUE 'display_more' ##NO_TEXT,
END OF c_actions .
METHODS constructor
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
DATA: mo_repo TYPE REF TO zcl_abapgit_repo,
mv_cur_dir TYPE string,
mv_hide_files TYPE abap_bool,
mv_max_lines TYPE i,
mv_max_setting TYPE i,
mv_show_folders TYPE abap_bool,
mv_changes_only TYPE abap_bool.
METHODS:
render_head_line
IMPORTING iv_lstate TYPE char1
iv_rstate TYPE char1
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
build_head_menu
IMPORTING iv_lstate TYPE char1
iv_rstate TYPE char1
RETURNING VALUE(ro_toolbar) TYPE REF TO zcl_abapgit_html_toolbar
RAISING zcx_abapgit_exception,
build_grid_menu
RETURNING VALUE(ro_toolbar) TYPE REF TO zcl_abapgit_html_toolbar
RAISING zcx_abapgit_exception,
render_item
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception,
render_item_files
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
render_item_command
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
get_item_class
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(rv_html) TYPE string,
get_item_icon
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(rv_html) TYPE string,
render_empty_package
RETURNING VALUE(rv_html) TYPE string,
render_parent_dir
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html
RAISING zcx_abapgit_exception.
METHODS:
build_obj_jump_link
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_repo_item
RETURNING VALUE(rv_html) TYPE string,
build_dir_jump_link
IMPORTING iv_path TYPE string
RETURNING VALUE(rv_html) TYPE string.
ENDCLASS.
CLASS zcl_abapgit_gui_view_tutorial DEFINITION FINAL CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES zif_abapgit_gui_page.
INTERFACES zif_abapgit_gui_page_hotkey.
ALIASES render FOR zif_abapgit_gui_page~render.
PRIVATE SECTION.
METHODS render_content
RETURNING VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
ENDCLASS.
CLASS zcl_abapgit_hotkeys DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS:
get_default_hotkeys_from_pages
RETURNING
VALUE(rt_hotkey_actions) TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action
RAISING
zcx_abapgit_exception,
get_relevant_hotkeys_for_page
IMPORTING
io_page TYPE REF TO zcl_abapgit_gui_page
RETURNING
VALUE(rt_hotkeys) TYPE zif_abapgit_definitions=>tty_hotkey
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_html DEFINITION
CREATE PUBLIC.
PUBLIC SECTION.
CONSTANTS c_indent_size TYPE i VALUE 2 ##NO_TEXT.
CLASS-METHODS class_constructor .
METHODS add
IMPORTING
!ig_chunk TYPE any .
METHODS render
IMPORTING
!iv_no_indent_jscss TYPE abap_bool OPTIONAL
RETURNING
VALUE(rv_html) TYPE string .
METHODS is_empty
RETURNING
VALUE(rv_yes) TYPE abap_bool .
METHODS add_a
IMPORTING
!iv_txt TYPE string
!iv_act TYPE string
!iv_typ TYPE char1 DEFAULT zif_abapgit_definitions=>c_action_type-sapevent
!iv_opt TYPE clike OPTIONAL
!iv_class TYPE string OPTIONAL
!iv_id TYPE string OPTIONAL
!iv_style TYPE string OPTIONAL.
METHODS add_icon
IMPORTING
!iv_name TYPE string
!iv_hint TYPE string OPTIONAL
!iv_class TYPE string OPTIONAL .
CLASS-METHODS a
IMPORTING
!iv_txt TYPE string
!iv_act TYPE string
!iv_typ TYPE char1 DEFAULT zif_abapgit_definitions=>c_action_type-sapevent
!iv_opt TYPE clike OPTIONAL
!iv_class TYPE string OPTIONAL
!iv_id TYPE string OPTIONAL
!iv_style TYPE string OPTIONAL
RETURNING
VALUE(rv_str) TYPE string .
CLASS-METHODS icon
IMPORTING
!iv_name TYPE string
!iv_hint TYPE string OPTIONAL
!iv_class TYPE string OPTIONAL
RETURNING
VALUE(rv_str) TYPE string .
PRIVATE SECTION.
CLASS-DATA: go_single_tags_re TYPE REF TO cl_abap_regex.
DATA: mt_buffer TYPE string_table.
TYPES:
BEGIN OF ty_indent_context,
no_indent_jscss TYPE abap_bool,
within_style TYPE abap_bool,
within_js TYPE abap_bool,
indent TYPE i,
indent_str TYPE string,
END OF ty_indent_context,
BEGIN OF ty_study_result,
style_open TYPE abap_bool,
style_close TYPE abap_bool,
script_open TYPE abap_bool,
script_close TYPE abap_bool,
tag_close TYPE abap_bool,
curly_close TYPE abap_bool,
openings TYPE i,
closings TYPE i,
singles TYPE i,
END OF ty_study_result.
METHODS indent_line
CHANGING
cs_context TYPE ty_indent_context
cv_line TYPE string.
METHODS study_line
IMPORTING iv_line TYPE string
is_context TYPE ty_indent_context
RETURNING VALUE(rs_result) TYPE ty_study_result.
ENDCLASS.
CLASS zcl_abapgit_html_action_utils DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS field_keys_to_upper
CHANGING
!ct_fields TYPE tihttpnvp .
CLASS-METHODS parse_fields
IMPORTING
!iv_string TYPE clike
RETURNING
VALUE(rt_fields) TYPE tihttpnvp .
CLASS-METHODS parse_fields_upper_case_name
IMPORTING
!iv_string TYPE clike
RETURNING
VALUE(rt_fields) TYPE tihttpnvp .
CLASS-METHODS add_field
IMPORTING
!iv_name TYPE string
!ig_field TYPE any
CHANGING
!ct_field TYPE tihttpnvp .
CLASS-METHODS get_field
IMPORTING
!iv_name TYPE string
!it_field TYPE tihttpnvp
CHANGING
!cg_field TYPE any .
CLASS-METHODS jump_encode
IMPORTING
!iv_obj_type TYPE tadir-object
!iv_obj_name TYPE tadir-obj_name
RETURNING
VALUE(rv_string) TYPE string .
CLASS-METHODS jump_decode
IMPORTING
!iv_string TYPE clike
EXPORTING
!ev_obj_type TYPE tadir-object
!ev_obj_name TYPE tadir-obj_name
RAISING
zcx_abapgit_exception .
CLASS-METHODS dir_encode
IMPORTING
!iv_path TYPE string
RETURNING
VALUE(rv_string) TYPE string .
CLASS-METHODS dir_decode
IMPORTING
!iv_string TYPE clike
RETURNING
VALUE(rv_path) TYPE string
RAISING
zcx_abapgit_exception .
CLASS-METHODS file_encode
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!ig_file TYPE any "assuming ty_file
RETURNING
VALUE(rv_string) TYPE string .
CLASS-METHODS obj_encode
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
!ig_object TYPE any "assuming ty_item
RETURNING
VALUE(rv_string) TYPE string .
CLASS-METHODS file_obj_decode
IMPORTING
!iv_string TYPE clike
EXPORTING
!ev_key TYPE zif_abapgit_persistence=>ty_repo-key
!eg_file TYPE any "assuming ty_file
!eg_object TYPE any "assuming ty_item
RAISING
zcx_abapgit_exception .
CLASS-METHODS dbkey_encode
IMPORTING
!is_key TYPE zif_abapgit_persistence=>ty_content
RETURNING
VALUE(rv_string) TYPE string .
CLASS-METHODS dbkey_decode
IMPORTING
!iv_string TYPE clike
RETURNING
VALUE(rs_key) TYPE zif_abapgit_persistence=>ty_content .
CLASS-METHODS stage_decode
IMPORTING
!iv_getdata TYPE clike
EXPORTING
!ev_key TYPE zif_abapgit_persistence=>ty_repo-key
!ev_seed TYPE string
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
CLASS-METHODS unescape
IMPORTING iv_string TYPE string
RETURNING VALUE(rv_string) TYPE string.
ENDCLASS.
CLASS zcl_abapgit_html_toolbar DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
METHODS:
constructor
IMPORTING
iv_id TYPE string OPTIONAL,
add
IMPORTING
iv_txt TYPE string
io_sub TYPE REF TO zcl_abapgit_html_toolbar OPTIONAL
iv_typ TYPE c DEFAULT zif_abapgit_definitions=>c_action_type-sapevent
iv_act TYPE string OPTIONAL
iv_ico TYPE string OPTIONAL
iv_cur TYPE abap_bool OPTIONAL
iv_opt TYPE c OPTIONAL
iv_chk TYPE abap_bool DEFAULT abap_undefined
iv_aux TYPE string OPTIONAL
iv_id TYPE string OPTIONAL,
count
RETURNING VALUE(rv_count) TYPE i,
render
IMPORTING
iv_right TYPE abap_bool OPTIONAL
iv_sort TYPE abap_bool OPTIONAL
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html,
render_as_droplist
IMPORTING
iv_label TYPE string
iv_right TYPE abap_bool OPTIONAL
iv_sort TYPE abap_bool OPTIONAL
iv_corner TYPE abap_bool OPTIONAL
iv_action TYPE string OPTIONAL
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_item,
txt TYPE string,
act TYPE string,
ico TYPE string,
sub TYPE REF TO zcl_abapgit_html_toolbar,
opt TYPE char1,
typ TYPE char1,
cur TYPE abap_bool,
chk TYPE abap_bool,
aux TYPE string,
id TYPE string,
END OF ty_item.
TYPES tt_items TYPE STANDARD TABLE OF ty_item.
DATA: mt_items TYPE tt_items,
mv_id TYPE string.
METHODS:
render_items
IMPORTING
iv_sort TYPE abap_bool OPTIONAL
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html.
ENDCLASS.
CLASS zcl_abapgit_password_dialog DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS popup
IMPORTING
!iv_repo_url TYPE string
CHANGING
!cv_user TYPE string
!cv_pass TYPE string .
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_popups DEFINITION
FINAL
CREATE PRIVATE
FRIENDS ZCL_ABAPGIT_ui_factory.
PUBLIC SECTION.
INTERFACES: zif_abapgit_popups.
ALIASES:
popup_package_export FOR zif_abapgit_popups~popup_package_export,
popup_folder_logic FOR zif_abapgit_popups~popup_folder_logic,
popup_object FOR zif_abapgit_popups~popup_object,
create_branch_popup FOR zif_abapgit_popups~create_branch_popup,
run_page_class_popup FOR zif_abapgit_popups~run_page_class_popup,
repo_new_offline FOR zif_abapgit_popups~repo_new_offline,
branch_list_popup FOR zif_abapgit_popups~branch_list_popup,
repo_popup FOR zif_abapgit_popups~repo_popup,
popup_to_confirm FOR zif_abapgit_popups~popup_to_confirm,
popup_to_inform FOR zif_abapgit_popups~popup_to_inform,
popup_to_create_package FOR zif_abapgit_popups~popup_to_create_package,
popup_to_create_transp_branch FOR zif_abapgit_popups~popup_to_create_transp_branch,
popup_to_select_transports FOR zif_abapgit_popups~popup_to_select_transports,
popup_to_select_from_list FOR zif_abapgit_popups~popup_to_select_from_list,
branch_popup_callback FOR zif_abapgit_popups~branch_popup_callback,
package_popup_callback FOR zif_abapgit_popups~package_popup_callback,
popup_transport_request FOR zif_abapgit_popups~popup_transport_request.
PRIVATE SECTION.
TYPES:
ty_sval_tt TYPE STANDARD TABLE OF sval WITH DEFAULT KEY.
CONSTANTS c_fieldname_selected TYPE lvc_fname VALUE `SELECTED` ##NO_TEXT.
DATA go_select_list_popup TYPE REF TO cl_salv_table .
DATA gr_table TYPE REF TO data .
DATA gv_cancel TYPE abap_bool .
DATA go_table_descr TYPE REF TO cl_abap_tabledescr .
METHODS add_field
IMPORTING
!iv_tabname TYPE sval-tabname
!iv_fieldname TYPE sval-fieldname
!iv_fieldtext TYPE sval-fieldtext
!iv_value TYPE clike DEFAULT ''
!iv_field_attr TYPE sval-field_attr DEFAULT ''
!iv_obligatory TYPE spo_obl OPTIONAL
CHANGING
!ct_fields TYPE ty_sval_tt .
METHODS create_new_table
IMPORTING
!it_list TYPE STANDARD TABLE .
METHODS get_selected_rows
EXPORTING
!et_list TYPE INDEX TABLE .
METHODS on_select_list_link_click
FOR EVENT link_click OF cl_salv_events_table
IMPORTING
!row
!column .
METHODS on_select_list_function_click
FOR EVENT added_function OF cl_salv_events_table
IMPORTING
!e_salv_function .
METHODS extract_field_values
IMPORTING
it_fields TYPE ty_sval_tt
EXPORTING
ev_url TYPE abaptxt255-line
ev_package TYPE tdevc-devclass
ev_branch TYPE textl-line .
ENDCLASS.
CLASS zcl_abapgit_services_abapgit DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CONSTANTS c_abapgit_homepage TYPE string VALUE 'http://www.abapgit.org' ##NO_TEXT.
CONSTANTS c_abapgit_wikipage TYPE string VALUE 'http://docs.abapgit.org' ##NO_TEXT.
CONSTANTS c_package_abapgit TYPE devclass VALUE '$ABAPGIT' ##NO_TEXT.
CONSTANTS c_abapgit_url TYPE string VALUE 'https://github.com/larshp/abapGit.git' ##NO_TEXT.
CLASS-METHODS open_abapgit_homepage
RAISING
zcx_abapgit_exception .
CLASS-METHODS open_abapgit_wikipage
RAISING
zcx_abapgit_exception .
CLASS-METHODS install_abapgit
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS is_installed
RETURNING
VALUE(rv_installed) TYPE abap_bool .
PRIVATE SECTION.
CLASS-METHODS do_install
IMPORTING iv_title TYPE c
iv_text TYPE c
iv_url TYPE string
iv_package TYPE devclass
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_services_git DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
BEGIN OF ty_commit_fields,
repo_key TYPE zif_abapgit_persistence=>ty_repo-key,
committer_name TYPE string,
committer_email TYPE string,
author_name TYPE string,
author_email TYPE string,
comment TYPE string,
body TYPE string,
END OF ty_commit_fields.
CLASS-METHODS pull
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS reset
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS create_branch
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS switch_branch
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS delete_branch
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS delete_tag
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS switch_tag
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS tag_overview
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS commit
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
!is_commit TYPE ty_commit_fields
!io_stage TYPE REF TO zcl_abapgit_stage
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_services_repo DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS new_online
IMPORTING
!iv_url TYPE string
RETURNING
VALUE(ro_repo) TYPE REF TO zcl_abapgit_repo_online
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS refresh
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
CLASS-METHODS remove
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS purge
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS new_offline
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS remote_attach
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS remote_detach
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS remote_change
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS refresh_local_checksums
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS toggle_favorite
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_repo-key
RAISING
zcx_abapgit_exception .
CLASS-METHODS open_se80
IMPORTING
!iv_package TYPE devclass
RAISING
zcx_abapgit_exception .
CLASS-METHODS transport_to_branch
IMPORTING
!iv_repository_key TYPE zif_abapgit_persistence=>ty_value
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS gui_deserialize
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
CLASS-METHODS popup_overwrite
CHANGING
!ct_overwrite TYPE zif_abapgit_definitions=>ty_overwrite_tt
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS popup_package_overwrite
CHANGING
!ct_overwrite TYPE zif_abapgit_definitions=>ty_overwrite_tt
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
ENDCLASS.
CLASS zcl_abapgit_tag_popups DEFINITION
FINAL
CREATE PRIVATE
FRIENDS ZCL_ABAPGIT_ui_factory.
PUBLIC SECTION.
INTERFACES: zif_abapgit_tag_popups.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_tag_out.
include structure zif_abapgit_definitions=>ty_git_tag.
TYPES: body_icon TYPE icon_d,
END OF ty_tag_out,
tty_tag_out TYPE STANDARD TABLE OF ty_tag_out
WITH NON-UNIQUE DEFAULT KEY.
DATA:
mt_tags TYPE tty_tag_out,
mo_docking_container TYPE REF TO cl_gui_docking_container,
mo_text_control TYPE REF TO cl_gui_textedit.
METHODS:
on_double_click FOR EVENT double_click OF cl_salv_events_table
IMPORTING row column,
prepare_tags_for_display
IMPORTING
it_tags TYPE zif_abapgit_definitions=>ty_git_tag_list_tt
RETURNING
VALUE(rt_tags_out) TYPE zcl_abapgit_tag_popups=>tty_tag_out,
clean_up,
show_docking_container_with
IMPORTING
iv_text TYPE string.
ENDCLASS.
CLASS zcl_abapgit_ui_factory DEFINITION
CREATE PRIVATE
FRIENDS ZCL_ABAPGIT_ui_injector.
PUBLIC SECTION.
CLASS-METHODS:
get_popups
RETURNING
VALUE(ri_popups) TYPE REF TO zif_abapgit_popups,
get_tag_popups
RETURNING
VALUE(ri_tag_popups) TYPE REF TO zif_abapgit_tag_popups.
PRIVATE SECTION.
CLASS-DATA:
mi_popups TYPE REF TO zif_abapgit_popups,
mi_tag_popups TYPE REF TO zif_abapgit_tag_popups.
ENDCLASS.
CLASS zcl_abapgit_ui_injector DEFINITION
CREATE PRIVATE.
PUBLIC SECTION.
CLASS-METHODS:
set_popups
IMPORTING
ii_popups TYPE REF TO zif_abapgit_popups,
set_tag_popups
IMPORTING
ii_tag_popups TYPE REF TO zif_abapgit_tag_popups.
ENDCLASS.
CLASS zcl_abapgit_convert DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS bitbyte_to_int
IMPORTING
!iv_bits TYPE clike
RETURNING
VALUE(rv_int) TYPE i .
CLASS-METHODS x_to_bitbyte
IMPORTING
!iv_x TYPE x
RETURNING
VALUE(rv_bitbyte) TYPE zif_abapgit_definitions=>ty_bitbyte .
CLASS-METHODS string_to_xstring_utf8
IMPORTING
!iv_string TYPE string
RETURNING
VALUE(rv_xstring) TYPE xstring .
CLASS-METHODS xstring_to_string_utf8
IMPORTING
!iv_data TYPE xstring
RETURNING
VALUE(rv_string) TYPE string .
CLASS-METHODS xstring_to_int
IMPORTING
!iv_xstring TYPE xstring
RETURNING
VALUE(rv_i) TYPE i
RAISING
zcx_abapgit_exception .
CLASS-METHODS int_to_xstring4
IMPORTING
!iv_i TYPE i
RETURNING
VALUE(rv_xstring) TYPE xstring .
CLASS-METHODS split_string
IMPORTING
!iv_string TYPE string
RETURNING
VALUE(rt_lines) TYPE string_table .
ENDCLASS.
CLASS zcl_abapgit_diff DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
DATA mt_beacons TYPE zif_abapgit_definitions=>ty_string_tt READ-ONLY.
METHODS constructor
IMPORTING iv_new TYPE xstring
iv_old TYPE xstring.
METHODS get
RETURNING VALUE(rt_diff) TYPE zif_abapgit_definitions=>ty_diffs_tt.
METHODS stats
RETURNING VALUE(rs_count) TYPE zif_abapgit_definitions=>ty_count.
PRIVATE SECTION.
DATA mt_diff TYPE zif_abapgit_definitions=>ty_diffs_tt.
DATA ms_stats TYPE zif_abapgit_definitions=>ty_count.
CLASS-METHODS:
unpack
IMPORTING iv_new TYPE xstring
iv_old TYPE xstring
EXPORTING et_new TYPE abaptxt255_tab
et_old TYPE abaptxt255_tab,
render
IMPORTING it_new TYPE abaptxt255_tab
it_old TYPE abaptxt255_tab
it_delta TYPE vxabapt255_tab
RETURNING VALUE(rt_diff) TYPE zif_abapgit_definitions=>ty_diffs_tt,
compute
IMPORTING it_new TYPE abaptxt255_tab
it_old TYPE abaptxt255_tab
RETURNING VALUE(rt_delta) TYPE vxabapt255_tab.
METHODS:
calculate_line_num_and_stats,
map_beacons,
shortlist.
ENDCLASS.
CLASS zcl_abapgit_hash DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS adler32
IMPORTING
!iv_xstring TYPE xstring
RETURNING
VALUE(rv_checksum) TYPE zif_abapgit_definitions=>ty_adler32 .
CLASS-METHODS sha1
IMPORTING
!iv_type TYPE zif_abapgit_definitions=>ty_type
!iv_data TYPE xstring
RETURNING
VALUE(rv_sha1) TYPE zif_abapgit_definitions=>ty_sha1
RAISING
zcx_abapgit_exception .
CLASS-METHODS sha1_raw
IMPORTING
!iv_data TYPE xstring
RETURNING
VALUE(rv_sha1) TYPE zif_abapgit_definitions=>ty_sha1
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_language DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS class_constructor .
CLASS-METHODS restore_login_language .
CLASS-METHODS set_current_language
IMPORTING
!iv_language TYPE langu .
PRIVATE SECTION.
CLASS-DATA gv_login_language TYPE langu .
ENDCLASS.
CLASS zcl_abapgit_log DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
METHODS add
IMPORTING
!iv_msg TYPE csequence
!iv_type TYPE symsgty DEFAULT 'E'
!iv_rc TYPE balsort OPTIONAL .
METHODS add_error
IMPORTING
!iv_msg TYPE csequence .
METHODS add_info
IMPORTING
!iv_msg TYPE csequence .
METHODS add_warning
IMPORTING
!iv_msg TYPE csequence .
METHODS clear .
METHODS count
RETURNING
VALUE(rv_count) TYPE i .
METHODS has_rc
IMPORTING
!iv_rc TYPE balsort
RETURNING
VALUE(rv_yes) TYPE abap_bool .
METHODS show
IMPORTING
!iv_header_text TYPE csequence DEFAULT 'Log' .
METHODS to_html
RETURNING
VALUE(ro_html) TYPE REF TO zcl_abapgit_html .
METHODS write .
PROTECTED SECTION.
TYPES:
BEGIN OF ty_log,
msg TYPE string,
type TYPE symsgty,
rc TYPE balsort,
END OF ty_log .
TYPES:
BEGIN OF ty_log_out,
type TYPE icon_d,
msg TYPE string,
END OF ty_log_out .
TYPES:
tty_log_out TYPE STANDARD TABLE OF ty_log_out
WITH NON-UNIQUE DEFAULT KEY .
DATA:
mt_log TYPE STANDARD TABLE OF ty_log WITH DEFAULT KEY .
METHODS prepare_log_for_display
RETURNING
VALUE(rt_log_out) TYPE zcl_abapgit_log=>tty_log_out .
ENDCLASS.
CLASS zcl_abapgit_login_manager DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS load
IMPORTING
!iv_uri TYPE string
!ii_client TYPE REF TO if_http_client OPTIONAL
RETURNING
VALUE(rv_authorization) TYPE string
RAISING
zcx_abapgit_exception .
CLASS-METHODS save
IMPORTING
!iv_uri TYPE string
!ii_client TYPE REF TO if_http_client
RAISING
zcx_abapgit_exception .
CLASS-METHODS clear .
CLASS-METHODS set
IMPORTING
!iv_uri TYPE string
!iv_username TYPE string
!iv_password TYPE string
RETURNING
VALUE(rv_auth) TYPE string
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
TYPES:
BEGIN OF ty_auth,
uri TYPE string,
authorization TYPE string,
END OF ty_auth .
CLASS-DATA:
gt_auth TYPE TABLE OF ty_auth WITH DEFAULT KEY.
CLASS-METHODS:
append
IMPORTING
!iv_uri TYPE string
!iv_auth TYPE string
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_path DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS split_file_location
IMPORTING iv_fullpath TYPE string
EXPORTING ev_path TYPE string
ev_filename TYPE string.
CLASS-METHODS is_root
IMPORTING iv_path TYPE string
RETURNING VALUE(rv_yes) TYPE abap_bool.
CLASS-METHODS is_subdir
IMPORTING iv_path TYPE string
iv_parent TYPE string
RETURNING VALUE(rv_yes) TYPE abap_bool.
CLASS-METHODS change_dir
IMPORTING iv_cur_dir TYPE string
iv_cd TYPE string
RETURNING VALUE(rv_path) TYPE string.
CLASS-METHODS get_filename_from_syspath
IMPORTING iv_path TYPE string
RETURNING VALUE(rv_filename) TYPE string.
ENDCLASS.
CLASS zcl_abapgit_progress DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS show
IMPORTING
VALUE(iv_current) TYPE i
!iv_text TYPE csequence .
METHODS constructor
IMPORTING
!iv_total TYPE i .
PROTECTED SECTION.
DATA mv_total TYPE i .
METHODS calc_pct
IMPORTING
!iv_current TYPE i
RETURNING
VALUE(rv_pct) TYPE i .
PRIVATE SECTION.
DATA mv_cv_time_next TYPE sy-uzeit .
DATA mv_cv_datum_next TYPE sy-datum .
ENDCLASS.
CLASS zcl_abapgit_requirement_helper DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
BEGIN OF ty_requirement_status,
met TYPE abap_bool,
component TYPE dlvunit,
description TYPE text80,
installed_release TYPE saprelease,
installed_patch TYPE sappatchlv,
required_release TYPE saprelease,
required_patch TYPE sappatchlv,
END OF ty_requirement_status .
TYPES:
ty_requirement_status_tt TYPE STANDARD TABLE OF ty_requirement_status WITH DEFAULT KEY .
CLASS-METHODS requirements_popup
IMPORTING
!it_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS is_requirements_met
IMPORTING
!it_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt
RETURNING
VALUE(rv_status) TYPE zif_abapgit_definitions=>ty_yes_no
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
CLASS-METHODS show_requirement_popup
IMPORTING
!it_requirements TYPE ty_requirement_status_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS get_requirement_met_status
IMPORTING
!it_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt
RETURNING
VALUE(rt_status) TYPE ty_requirement_status_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS version_greater_or_equal
IMPORTING
!is_status TYPE ty_requirement_status
RETURNING
VALUE(rv_true) TYPE abap_bool .
ENDCLASS.
CLASS zcl_abapgit_state DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS:
reduce
IMPORTING
!iv_cur TYPE char1
CHANGING
!cv_prev TYPE char1 .
ENDCLASS.
CLASS zcl_abapgit_time DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: ty_unixtime TYPE c LENGTH 16.
CLASS-METHODS get
RETURNING VALUE(rv_time) TYPE ty_unixtime
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CONSTANTS: c_epoch TYPE datum VALUE '19700101'.
ENDCLASS.
CLASS zcl_abapgit_url DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS validate
IMPORTING
!iv_url TYPE string
RAISING
zcx_abapgit_exception .
CLASS-METHODS host
IMPORTING
!iv_url TYPE string
RETURNING
VALUE(rv_host) TYPE string
RAISING
zcx_abapgit_exception .
CLASS-METHODS name
IMPORTING
!iv_url TYPE string
RETURNING
VALUE(rv_name) TYPE string
RAISING
zcx_abapgit_exception .
CLASS-METHODS path_name
IMPORTING
!iv_url TYPE string
RETURNING
VALUE(rv_path_name) TYPE string
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
CLASS-METHODS regex
IMPORTING
!iv_url TYPE string
EXPORTING
!ev_host TYPE string
!ev_path TYPE string
!ev_name TYPE string
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_user_master_record DEFINITION
FINAL
CREATE PRIVATE .
PUBLIC SECTION.
CLASS-METHODS:
get_instance
IMPORTING
!iv_user TYPE uname
RETURNING
VALUE(ro_user) TYPE REF TO zcl_abapgit_user_master_record.
METHODS:
constructor
IMPORTING
!iv_user TYPE uname,
get_name
RETURNING
VALUE(rv_name) TYPE zif_abapgit_definitions=>ty_git_user-name,
get_email
RETURNING
VALUE(rv_email) TYPE zif_abapgit_definitions=>ty_git_user-email.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_user,
user TYPE uname,
o_user TYPE REF TO zcl_abapgit_user_master_record,
END OF ty_user.
CLASS-DATA:
mt_user TYPE HASHED TABLE OF ty_user
WITH UNIQUE KEY user.
DATA:
ms_user TYPE zif_abapgit_definitions=>ty_git_user.
ENDCLASS.
CLASS zcl_abapgit_xml DEFINITION
ABSTRACT
CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
constructor.
PROTECTED SECTION.
DATA: mi_ixml TYPE REF TO if_ixml,
mi_xml_doc TYPE REF TO if_ixml_document,
ms_metadata TYPE zif_abapgit_definitions=>ty_metadata.
CONSTANTS: c_abapgit_tag TYPE string VALUE 'abapGit' ##NO_TEXT,
c_attr_version TYPE string VALUE 'version' ##NO_TEXT,
c_attr_serializer TYPE string VALUE 'serializer' ##NO_TEXT,
c_attr_serializer_version TYPE string VALUE 'serializer_version' ##NO_TEXT.
METHODS to_xml
IMPORTING iv_normalize TYPE sap_bool DEFAULT abap_true
RETURNING VALUE(rv_xml) TYPE string.
METHODS parse
IMPORTING iv_normalize TYPE abap_bool DEFAULT abap_true
iv_xml TYPE string
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
METHODS error
IMPORTING ii_parser TYPE REF TO if_ixml_parser
RAISING zcx_abapgit_exception.
METHODS display_xml_error
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_xml_input DEFINITION
INHERITING FROM zcl_abapgit_xml
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!iv_xml TYPE clike
RAISING
zcx_abapgit_exception .
METHODS read
IMPORTING
!iv_name TYPE clike
CHANGING
!cg_data TYPE any
RAISING
zcx_abapgit_exception .
METHODS get_raw
RETURNING
VALUE(ri_raw) TYPE REF TO if_ixml_document .
METHODS get_metadata
RETURNING
VALUE(rs_metadata) TYPE zif_abapgit_definitions=>ty_metadata .
PRIVATE SECTION.
METHODS: fix_xml.
ENDCLASS.
CLASS zcl_abapgit_xml_output DEFINITION
INHERITING FROM zcl_abapgit_xml
CREATE PUBLIC.
PUBLIC SECTION.
METHODS add
IMPORTING
!iv_name TYPE clike
!ig_data TYPE any
RAISING
zcx_abapgit_exception .
METHODS set_raw
IMPORTING
!ii_raw TYPE REF TO if_ixml_element .
METHODS add_xml
IMPORTING
!iv_name TYPE clike
!ii_xml TYPE REF TO if_ixml_element .
METHODS build_asx_node
RETURNING
VALUE(ri_element) TYPE REF TO if_ixml_element .
METHODS render
IMPORTING
!iv_normalize TYPE sap_bool DEFAULT abap_true
!is_metadata TYPE zif_abapgit_definitions=>ty_metadata OPTIONAL
RETURNING
VALUE(rv_xml) TYPE string .
PROTECTED SECTION.
PRIVATE SECTION.
DATA: mi_raw TYPE REF TO if_ixml_element.
ENDCLASS.
CLASS zcl_abapgit_xml_pretty DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS: print
IMPORTING iv_xml TYPE string
iv_ignore_errors TYPE abap_bool DEFAULT abap_true
iv_unpretty TYPE abap_bool DEFAULT abap_false
RETURNING VALUE(rv_xml) TYPE string
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_auth DEFINITION FINAL CREATE PUBLIC.
PUBLIC SECTION.
CLASS-METHODS:
is_allowed
IMPORTING iv_authorization TYPE zif_abapgit_auth=>ty_authorization
iv_param TYPE string OPTIONAL
RETURNING VALUE(rv_allowed) TYPE abap_bool.
ENDCLASS.
CLASS zcl_abapgit_branch_overview DEFINITION
FINAL
CREATE PRIVATE
FRIENDS ZCL_ABAPGIT_factory .
PUBLIC SECTION.
INTERFACES zif_abapgit_branch_overview .
METHODS constructor
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
TYPES:
ty_commits TYPE STANDARD TABLE OF zif_abapgit_definitions=>ty_commit WITH DEFAULT KEY .
DATA mt_branches TYPE zif_abapgit_definitions=>ty_git_branch_list_tt .
DATA mt_commits TYPE ty_commits .
DATA mt_tags TYPE zif_abapgit_definitions=>ty_git_tag_list_tt .
CLASS-METHODS parse_commits
IMPORTING
!it_objects TYPE zif_abapgit_definitions=>ty_objects_tt
RETURNING
VALUE(rt_commits) TYPE ty_commits
RAISING
zcx_abapgit_exception .
METHODS parse_annotated_tags
IMPORTING
!it_objects TYPE zif_abapgit_definitions=>ty_objects_tt
RAISING
zcx_abapgit_exception .
METHODS determine_branch
RAISING
zcx_abapgit_exception .
METHODS determine_merges
RAISING
zcx_abapgit_exception .
METHODS fixes
RAISING
zcx_abapgit_exception .
METHODS get_git_objects
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
RETURNING
VALUE(rt_objects) TYPE zif_abapgit_definitions=>ty_objects_tt
RAISING
zcx_abapgit_exception .
METHODS determine_tags
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_code_inspector DEFINITION
CREATE PROTECTED
FRIENDS ZCL_ABAPGIT_factory.
PUBLIC SECTION.
INTERFACES:
zif_abapgit_code_inspector.
METHODS:
constructor
IMPORTING
iv_package TYPE devclass
iv_check_variant_name TYPE sci_chkv OPTIONAL
RAISING
zcx_abapgit_exception.
CLASS-METHODS:
validate_check_variant
IMPORTING
iv_check_variant_name TYPE sci_chkv
RAISING
zcx_abapgit_exception.
PROTECTED SECTION.
TYPES:
ty_tdevc_tt TYPE STANDARD TABLE OF tdevc WITH DEFAULT KEY .
DATA:
mv_package TYPE devclass.
METHODS:
create_variant
RETURNING
VALUE(ro_variant) TYPE REF TO cl_ci_checkvariant
RAISING
zcx_abapgit_exception.
PRIVATE SECTION.
DATA:
mv_check_variant_name TYPE sci_chkv,
mo_inspection TYPE REF TO cl_ci_inspection.
METHODS:
find_all_subpackages
IMPORTING
iv_package TYPE devclass
RETURNING
VALUE(rt_packages) TYPE ty_tdevc_tt,
create_objectset
RETURNING
VALUE(ro_set) TYPE REF TO cl_ci_objectset,
run_inspection
IMPORTING
io_inspection TYPE REF TO cl_ci_inspection
RETURNING
VALUE(rt_list) TYPE scit_alvlist,
create_inspection
IMPORTING
io_set TYPE REF TO cl_ci_objectset
io_variant TYPE REF TO cl_ci_checkvariant
RETURNING
VALUE(ro_inspection) TYPE REF TO cl_ci_inspection.
ENDCLASS.
CLASS zcl_abapgit_default_transport DEFINITION
CREATE PRIVATE .
PUBLIC SECTION.
CLASS-METHODS:
get_instance
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_abapgit_default_transport
RAISING
zcx_abapgit_exception.
METHODS:
constructor
RAISING
zcx_abapgit_exception,
set
IMPORTING
iv_transport TYPE trkorr
RAISING
zcx_abapgit_exception,
reset
RAISING
zcx_abapgit_exception.
PRIVATE SECTION.
CLASS-DATA:
mo_instance TYPE REF TO zcl_abapgit_default_transport .
DATA:
mv_is_set_by_abapgit TYPE abap_bool,
ms_save TYPE e070use.
METHODS:
store
RAISING
zcx_abapgit_exception,
restore
RAISING
zcx_abapgit_exception,
get
RETURNING
VALUE(rs_default_task) TYPE e070use
RAISING
zcx_abapgit_exception,
set_internal
IMPORTING
iv_transport TYPE trkorr
RAISING
zcx_abapgit_exception,
clear
IMPORTING
is_default_task TYPE e070use
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_dependencies DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS resolve
CHANGING
!ct_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
TYPES:
BEGIN OF ty_dependency,
depname TYPE dd02l-tabname,
deptyp TYPE c LENGTH 4,
deplocal TYPE dd02l-as4local,
refname TYPE dd02l-tabname,
reftyp TYPE c LENGTH 4,
kind TYPE c LENGTH 1,
END OF ty_dependency .
TYPES:
tty_dedenpency TYPE STANDARD TABLE OF ty_dependency
WITH NON-UNIQUE DEFAULT KEY .
TYPES:
BEGIN OF ty_item,
obj_type TYPE tadir-object,
obj_name TYPE tadir-obj_name,
devclass TYPE devclass,
END OF ty_item .
CLASS-METHODS resolve_ddic
CHANGING
!ct_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS get_ddls_dependencies
IMPORTING
iv_ddls_name TYPE tadir-obj_name
RETURNING
VALUE(rt_dependency) TYPE tty_dedenpency .
CLASS-METHODS resolve_packages
CHANGING
ct_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt.
ENDCLASS.
CLASS zcl_abapgit_dot_abapgit DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS build_default
RETURNING
VALUE(ro_dot_abapgit) TYPE REF TO zcl_abapgit_dot_abapgit .
CLASS-METHODS deserialize
IMPORTING
!iv_xstr TYPE xstring
RETURNING
VALUE(ro_dot_abapgit) TYPE REF TO zcl_abapgit_dot_abapgit
RAISING
zcx_abapgit_exception .
METHODS constructor
IMPORTING
!is_data TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit .
METHODS serialize
RETURNING
VALUE(rv_xstr) TYPE xstring
RAISING
zcx_abapgit_exception .
METHODS get_data
RETURNING
VALUE(rs_data) TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit .
METHODS add_ignore
IMPORTING
!iv_path TYPE string
!iv_filename TYPE string .
METHODS is_ignored
IMPORTING
!iv_path TYPE string
!iv_filename TYPE string
RETURNING
VALUE(rv_ignored) TYPE abap_bool .
METHODS remove_ignore
IMPORTING
!iv_path TYPE string
!iv_filename TYPE string .
METHODS get_starting_folder
RETURNING
VALUE(rv_path) TYPE string .
METHODS get_folder_logic
RETURNING
VALUE(rv_logic) TYPE string .
METHODS set_folder_logic
IMPORTING
!iv_logic TYPE string .
METHODS set_starting_folder
IMPORTING
!iv_path TYPE string .
METHODS get_master_language
RETURNING
VALUE(rv_language) TYPE spras .
METHODS get_signature
RETURNING
VALUE(rs_signature) TYPE zif_abapgit_definitions=>ty_file_signature
RAISING
zcx_abapgit_exception .
METHODS get_requirements
RETURNING
VALUE(rt_requirements) TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt.
METHODS set_requirements
IMPORTING
it_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt.
PRIVATE SECTION.
DATA: ms_data TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit.
CLASS-METHODS:
to_xml
IMPORTING is_data TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit
RETURNING VALUE(rv_xml) TYPE string
RAISING zcx_abapgit_exception,
from_xml
IMPORTING iv_xml TYPE string
RETURNING VALUE(rs_data) TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit.
ENDCLASS.
CLASS zcl_abapgit_exit DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS: get_instance RETURNING VALUE(ri_exit) TYPE REF TO zif_abapgit_exit.
INTERFACES: zif_abapgit_exit.
PRIVATE SECTION.
CLASS-DATA gi_exit TYPE REF TO zif_abapgit_exit .
ENDCLASS.
CLASS zcl_abapgit_factory DEFINITION
CREATE PRIVATE
FRIENDS ZCL_ABAPGIT_injector.
PUBLIC SECTION.
CLASS-METHODS:
get_tadir
RETURNING
VALUE(ri_tadir) TYPE REF TO zif_abapgit_tadir,
get_sap_package
IMPORTING
iv_package TYPE devclass
RETURNING
VALUE(ri_sap_package) TYPE REF TO zif_abapgit_sap_package,
get_code_inspector
IMPORTING
iv_package TYPE devclass
iv_check_variant_name TYPE sci_chkv
RETURNING
VALUE(ri_code_inspector) TYPE REF TO zif_abapgit_code_inspector
RAISING
zcx_abapgit_exception,
get_syntax_check
IMPORTING
iv_package TYPE devclass
RETURNING
VALUE(ri_syntax_check) TYPE REF TO zif_abapgit_code_inspector
RAISING
zcx_abapgit_exception,
get_branch_overview
IMPORTING
io_repo TYPE REF TO zcl_abapgit_repo_online
RETURNING
VALUE(ri_branch_overview) TYPE REF TO zif_abapgit_branch_overview
RAISING
zcx_abapgit_exception.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_sap_package,
package TYPE devclass,
instance TYPE REF TO zif_abapgit_sap_package,
END OF ty_sap_package,
tty_sap_package TYPE HASHED TABLE OF ty_sap_package
WITH UNIQUE KEY package,
BEGIN OF ty_code_inspector,
package TYPE devclass,
check_variant_name TYPE sci_chkv,
instance TYPE REF TO zif_abapgit_code_inspector,
END OF ty_code_inspector,
tty_code_inspector TYPE HASHED TABLE OF ty_code_inspector
WITH UNIQUE KEY package check_variant_name,
BEGIN OF ty_syntax_check,
package TYPE devclass,
instance TYPE REF TO zif_abapgit_code_inspector,
END OF ty_syntax_check,
tty_syntax_check TYPE HASHED TABLE OF ty_syntax_check
WITH UNIQUE KEY package,
BEGIN OF ty_branch_overview,
repo_key TYPE zif_abapgit_persistence=>ty_value,
instance TYPE REF TO zif_abapgit_branch_overview,
END OF ty_branch_overview,
tty_branch_overview TYPE HASHED TABLE OF ty_branch_overview
WITH UNIQUE KEY repo_key.
CLASS-DATA:
gi_tadir TYPE REF TO zif_abapgit_tadir,
gt_sap_package TYPE tty_sap_package,
gt_code_inspector TYPE tty_code_inspector,
gt_syntax_check TYPE tty_syntax_check,
gi_branch_overview TYPE REF TO zif_abapgit_branch_overview.
ENDCLASS.
CLASS zcl_abapgit_file_status DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS status
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo
io_log TYPE REF TO zcl_abapgit_log OPTIONAL
RETURNING VALUE(rt_results) TYPE zif_abapgit_definitions=>ty_results_tt
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CLASS-METHODS:
calculate_status
IMPORTING iv_devclass TYPE devclass
io_dot TYPE REF TO zcl_abapgit_dot_abapgit
it_local TYPE zif_abapgit_definitions=>ty_files_item_tt
it_remote TYPE zif_abapgit_definitions=>ty_files_tt
it_cur_state TYPE zif_abapgit_definitions=>ty_file_signatures_tt
RETURNING VALUE(rt_results) TYPE zif_abapgit_definitions=>ty_results_tt
RAISING zcx_abapgit_exception,
run_checks
IMPORTING io_log TYPE REF TO zcl_abapgit_log
it_results TYPE zif_abapgit_definitions=>ty_results_tt
io_dot TYPE REF TO zcl_abapgit_dot_abapgit
iv_top TYPE devclass
RAISING zcx_abapgit_exception,
build_existing
IMPORTING is_local TYPE zif_abapgit_definitions=>ty_file_item
is_remote TYPE zif_abapgit_definitions=>ty_file
it_state TYPE zif_abapgit_definitions=>ty_file_signatures_ts
RETURNING VALUE(rs_result) TYPE zif_abapgit_definitions=>ty_result,
build_new_local
IMPORTING is_local TYPE zif_abapgit_definitions=>ty_file_item
RETURNING VALUE(rs_result) TYPE zif_abapgit_definitions=>ty_result,
build_new_remote
IMPORTING iv_devclass TYPE devclass
io_dot TYPE REF TO zcl_abapgit_dot_abapgit
is_remote TYPE zif_abapgit_definitions=>ty_file
it_items TYPE zif_abapgit_definitions=>ty_items_ts
it_state TYPE zif_abapgit_definitions=>ty_file_signatures_ts
RETURNING VALUE(rs_result) TYPE zif_abapgit_definitions=>ty_result
RAISING zcx_abapgit_exception,
identify_object
IMPORTING iv_filename TYPE string
iv_path TYPE string
iv_devclass TYPE devclass
io_dot TYPE REF TO zcl_abapgit_dot_abapgit
EXPORTING es_item TYPE zif_abapgit_definitions=>ty_item
ev_is_xml TYPE abap_bool
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_folder_logic DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
METHODS package_to_path
IMPORTING
!iv_top TYPE devclass
!io_dot TYPE REF TO zcl_abapgit_dot_abapgit
!iv_package TYPE devclass
RETURNING
VALUE(rv_path) TYPE string
RAISING
zcx_abapgit_exception .
METHODS path_to_package
IMPORTING
!iv_top TYPE devclass
!io_dot TYPE REF TO zcl_abapgit_dot_abapgit
!iv_path TYPE string
!iv_create_if_not_exists TYPE abap_bool DEFAULT abap_true
RETURNING
VALUE(rv_package) TYPE devclass
RAISING
zcx_abapgit_exception .
CLASS-METHODS get_instance
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_abapgit_folder_logic .
PROTECTED SECTION.
METHODS get_parent
IMPORTING
!iv_package TYPE devclass
RETURNING
VALUE(r_parent) TYPE devclass.
PRIVATE SECTION.
TYPES:
BEGIN OF ty_devclass_info,
devclass TYPE devclass,
namespace TYPE namespace,
parentcl TYPE parentcl,
END OF ty_devclass_info .
TYPES:
ty_devclass_info_tt TYPE SORTED TABLE OF ty_devclass_info
WITH UNIQUE KEY devclass .
DATA mt_parent TYPE ty_devclass_info_tt .
ENDCLASS.
CLASS zcl_abapgit_http_client DEFINITION CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING ii_client TYPE REF TO if_http_client,
close,
set_digest
IMPORTING io_digest TYPE REF TO zcl_abapgit_http_digest,
send_receive_close
IMPORTING
iv_data TYPE xstring
RETURNING
VALUE(rv_data) TYPE xstring
RAISING zcx_abapgit_exception,
get_cdata
RETURNING VALUE(rv_value) TYPE string,
check_http_200
RAISING zcx_abapgit_exception,
send_receive
RAISING zcx_abapgit_exception,
set_headers
IMPORTING iv_url TYPE string
iv_service TYPE string
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
DATA: mi_client TYPE REF TO if_http_client,
mo_digest TYPE REF TO zcl_abapgit_http_digest.
ENDCLASS.
CLASS zcl_abapgit_injector DEFINITION
CREATE PRIVATE
FOR TESTING .
PUBLIC SECTION.
CLASS-METHODS:
set_tadir
IMPORTING
!ii_tadir TYPE REF TO zif_abapgit_tadir,
set_sap_package
IMPORTING
iv_package TYPE devclass
ii_sap_package TYPE REF TO zif_abapgit_sap_package,
set_code_inspector
IMPORTING
iv_package TYPE devclass
iv_check_variant_name TYPE sci_chkv OPTIONAL
ii_code_inspector TYPE REF TO zif_abapgit_code_inspector,
set_syntax_check
IMPORTING
iv_package TYPE devclass
ii_syntax_check TYPE REF TO zif_abapgit_code_inspector.
ENDCLASS.
CLASS zcl_abapgit_merge DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
!iv_source_branch TYPE string
RAISING
zcx_abapgit_exception .
METHODS get_conflicts
RETURNING
VALUE(rt_conflicts) TYPE zif_abapgit_definitions=>tt_merge_conflict .
METHODS get_result
RETURNING
VALUE(rs_merge) TYPE zif_abapgit_definitions=>ty_merge .
METHODS get_source_branch
RETURNING
VALUE(rv_source_branch) TYPE string .
METHODS has_conflicts
RETURNING
VALUE(rv_conflicts_exists) TYPE boolean .
METHODS resolve_conflict
IMPORTING
!is_conflict TYPE zif_abapgit_definitions=>ty_merge_conflict
RAISING
zcx_abapgit_exception .
METHODS run
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
TYPES:
ty_ancestor_tt TYPE STANDARD TABLE OF zif_abapgit_definitions=>ty_ancestor WITH DEFAULT KEY .
DATA mo_repo TYPE REF TO zcl_abapgit_repo_online .
DATA ms_merge TYPE zif_abapgit_definitions=>ty_merge .
DATA mt_conflicts TYPE zif_abapgit_definitions=>tt_merge_conflict .
DATA mt_objects TYPE zif_abapgit_definitions=>ty_objects_tt .
DATA mv_source_branch TYPE string .
METHODS all_files
RETURNING
VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_expanded_tt .
METHODS calculate_result
RAISING
zcx_abapgit_exception .
METHODS fetch_git
RETURNING
VALUE(rt_objects) TYPE zif_abapgit_definitions=>ty_objects_tt
RAISING
zcx_abapgit_exception .
METHODS find_ancestors
IMPORTING
!iv_commit TYPE zif_abapgit_definitions=>ty_sha1
RETURNING
VALUE(rt_ancestors) TYPE ty_ancestor_tt
RAISING
zcx_abapgit_exception .
METHODS find_first_common
IMPORTING
!it_list1 TYPE ty_ancestor_tt
!it_list2 TYPE ty_ancestor_tt
RETURNING
VALUE(rs_common) TYPE zif_abapgit_definitions=>ty_ancestor
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_migrations DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS run
RAISING zcx_abapgit_exception.
PRIVATE SECTION.
CLASS-METHODS rebuild_local_checksums_161112
RAISING
zcx_abapgit_exception .
CLASS-METHODS local_dot_abapgit
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_news DEFINITION
FINAL
CREATE PRIVATE .
PUBLIC SECTION.
TYPES:
BEGIN OF ty_log,
version TYPE string,
pos_to_cur TYPE i,
is_header TYPE abap_bool,
is_important TYPE abap_bool,
text TYPE string,
END OF ty_log .
TYPES:
tt_log TYPE STANDARD TABLE OF ty_log WITH DEFAULT KEY .
CONSTANTS c_tail_length TYPE i VALUE 5 ##NO_TEXT. " Number of versions to display if no updates
CLASS-METHODS create " TODO REFACTOR
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
RETURNING
VALUE(ro_instance) TYPE REF TO zcl_abapgit_news
RAISING
zcx_abapgit_exception .
METHODS get_log
RETURNING
VALUE(rt_log) TYPE tt_log .
METHODS has_news
RETURNING
VALUE(rv_boolean) TYPE abap_bool .
METHODS has_important
RETURNING
VALUE(rv_boolean) TYPE abap_bool .
METHODS has_updates
RETURNING
VALUE(rv_boolean) TYPE abap_bool .
METHODS has_unseen
RETURNING
VALUE(rv_boolean) TYPE abap_bool .
PRIVATE SECTION.
DATA mt_log TYPE tt_log .
DATA mv_current_version TYPE string .
DATA mv_lastseen_version TYPE string .
DATA mv_latest_version TYPE string .
CLASS-METHODS is_relevant
IMPORTING
!iv_url TYPE string
RETURNING
VALUE(rv_relevant) TYPE abap_bool .
METHODS latest_version
RETURNING
VALUE(rv_version) TYPE string .
METHODS constructor
IMPORTING
!iv_rawdata TYPE xstring
!iv_lastseen_version TYPE string
!iv_current_version TYPE string .
CLASS-METHODS version_to_numeric
IMPORTING
!iv_version TYPE string
RETURNING
VALUE(rv_version) TYPE i .
CLASS-METHODS normalize_version
IMPORTING
!iv_version TYPE string
RETURNING
VALUE(rv_version) TYPE string .
CLASS-METHODS compare_versions
IMPORTING
!iv_a TYPE string
!iv_b TYPE string
RETURNING
VALUE(rv_result) TYPE i .
CLASS-METHODS parse_line
IMPORTING
!iv_line TYPE string
!iv_current_version TYPE string
RETURNING
VALUE(rs_log) TYPE ty_log .
CLASS-METHODS parse
IMPORTING
!it_lines TYPE string_table
!iv_current_version TYPE string
RETURNING
VALUE(rt_log) TYPE tt_log .
ENDCLASS.
CLASS zcl_abapgit_objects DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
ty_types_tt TYPE STANDARD TABLE OF tadir-object WITH DEFAULT KEY .
TYPES:
BEGIN OF ty_deserialization,
obj TYPE REF TO zif_abapgit_object,
xml TYPE REF TO zcl_abapgit_xml_input,
package TYPE devclass,
item TYPE zif_abapgit_definitions=>ty_item,
END OF ty_deserialization .
TYPES:
ty_deserialization_tt TYPE STANDARD TABLE OF ty_deserialization WITH DEFAULT KEY .
CLASS-METHODS serialize
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_language TYPE spras
!io_log TYPE REF TO zcl_abapgit_log OPTIONAL
RETURNING
VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_files_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS deserialize
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
!is_checks TYPE zif_abapgit_definitions=>ty_deserialize_checks
RETURNING
VALUE(rt_accessed_files) TYPE zif_abapgit_definitions=>ty_file_signatures_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS deserialize_checks
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
RETURNING
VALUE(rs_checks) TYPE zif_abapgit_definitions=>ty_deserialize_checks
RAISING
zcx_abapgit_exception .
CLASS-METHODS delete
IMPORTING
!it_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt
!is_checks TYPE zif_abapgit_definitions=>ty_delete_checks OPTIONAL
RAISING
zcx_abapgit_exception .
CLASS-METHODS jump
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
RAISING
zcx_abapgit_exception .
CLASS-METHODS changed_by
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
RETURNING
VALUE(rv_user) TYPE xubname
RAISING
zcx_abapgit_exception .
CLASS-METHODS has_changed_since
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_timestamp TYPE timestamp
RETURNING
VALUE(rv_changed) TYPE abap_bool
RAISING
zcx_abapgit_exception .
CLASS-METHODS is_supported
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
!iv_native_only TYPE abap_bool DEFAULT abap_false
RETURNING
VALUE(rv_bool) TYPE abap_bool .
CLASS-METHODS exists
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
RETURNING
VALUE(rv_bool) TYPE abap_bool .
CLASS-METHODS supported_list
RETURNING
VALUE(rt_types) TYPE ty_types_tt .
PROTECTED SECTION.
PRIVATE SECTION.
TYPES: BEGIN OF ty_obj_serializer_map,
item TYPE zif_abapgit_definitions=>ty_item,
metadata TYPE zif_abapgit_definitions=>ty_metadata,
END OF ty_obj_serializer_map,
tty_obj_serializer_map
TYPE SORTED TABLE OF ty_obj_serializer_map WITH UNIQUE KEY item.
CLASS-DATA gt_obj_serializer_map TYPE tty_obj_serializer_map.
CLASS-METHODS files_to_deserialize
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
RETURNING
VALUE(rt_results) TYPE zif_abapgit_definitions=>ty_results_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS check_duplicates
IMPORTING
!it_files TYPE zif_abapgit_definitions=>ty_files_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS prioritize_deser
IMPORTING
!it_results TYPE zif_abapgit_definitions=>ty_results_tt
RETURNING
VALUE(rt_results) TYPE zif_abapgit_definitions=>ty_results_tt .
CLASS-METHODS class_name
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
RETURNING
VALUE(rv_class_name) TYPE string .
CLASS-METHODS warning_overwrite_adjust
IMPORTING
!it_overwrite TYPE zif_abapgit_definitions=>ty_overwrite_tt
CHANGING
!ct_results TYPE zif_abapgit_definitions=>ty_results_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS checks_adjust
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
!is_checks TYPE zif_abapgit_definitions=>ty_deserialize_checks
CHANGING
!ct_results TYPE zif_abapgit_definitions=>ty_results_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS warning_overwrite_find
IMPORTING
!it_results TYPE zif_abapgit_definitions=>ty_results_tt
RETURNING
VALUE(rt_overwrite) TYPE zif_abapgit_definitions=>ty_overwrite_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS warning_package_adjust
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
!it_overwrite TYPE zif_abapgit_definitions=>ty_overwrite_tt
CHANGING
!ct_results TYPE zif_abapgit_definitions=>ty_results_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS warning_package_find
IMPORTING
!it_results TYPE zif_abapgit_definitions=>ty_results_tt
!io_repo TYPE REF TO zcl_abapgit_repo
RETURNING
VALUE(rt_overwrite) TYPE zif_abapgit_definitions=>ty_overwrite_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS update_package_tree
IMPORTING
!iv_package TYPE devclass .
CLASS-METHODS delete_obj
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
RAISING
zcx_abapgit_exception .
CLASS-METHODS compare_remote_to_local
IMPORTING
!ii_object TYPE REF TO zif_abapgit_object
!it_remote TYPE zif_abapgit_definitions=>ty_files_tt
!is_result TYPE zif_abapgit_definitions=>ty_result
RAISING
zcx_abapgit_exception .
CLASS-METHODS deserialize_objects
IMPORTING
it_objects TYPE ty_deserialization_tt
iv_ddic TYPE abap_bool DEFAULT abap_false
iv_descr TYPE string
CHANGING
ct_files TYPE zif_abapgit_definitions=>ty_file_signatures_tt
RAISING
zcx_abapgit_exception .
CLASS-METHODS check_objects_locked
IMPORTING
iv_language TYPE spras
it_items TYPE zif_abapgit_definitions=>ty_items_tt
RAISING
zcx_abapgit_exception.
CLASS-METHODS create_object
IMPORTING
is_item TYPE zif_abapgit_definitions=>ty_item
iv_language TYPE spras
is_metadata TYPE zif_abapgit_definitions=>ty_metadata OPTIONAL
iv_native_only TYPE abap_bool DEFAULT abap_false
RETURNING
VALUE(ri_obj) TYPE REF TO zif_abapgit_object
RAISING
zcx_abapgit_exception .
CLASS-METHODS map_tadir_to_items
IMPORTING
it_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt
RETURNING
VALUE(rt_items) TYPE zif_abapgit_definitions=>ty_items_tt.
CLASS-METHODS map_results_to_items
IMPORTING
it_results TYPE zif_abapgit_definitions=>ty_results_tt
RETURNING
VALUE(rt_items) TYPE zif_abapgit_definitions=>ty_items_tt.
ENDCLASS.
CLASS zcl_abapgit_objects_bridge DEFINITION FINAL CREATE PUBLIC INHERITING FROM zcl_abapgit_objects_super.
PUBLIC SECTION.
CLASS-METHODS class_constructor.
METHODS constructor
IMPORTING is_item TYPE zif_abapgit_definitions=>ty_item
RAISING cx_sy_create_object_error.
INTERFACES zif_abapgit_object.
ALIASES mo_files FOR zif_abapgit_object~mo_files.
PRIVATE SECTION.
DATA: mo_plugin TYPE REF TO object.
TYPES: BEGIN OF ty_s_objtype_map,
obj_typ TYPE trobjtype,
plugin_class TYPE seoclsname,
END OF ty_s_objtype_map,
ty_t_objtype_map TYPE SORTED TABLE OF ty_s_objtype_map WITH UNIQUE KEY obj_typ.
CLASS-DATA gt_objtype_map TYPE ty_t_objtype_map.
ENDCLASS.
CLASS zcl_abapgit_repo DEFINITION
ABSTRACT
CREATE PUBLIC
FRIENDS ZCL_ABAPGIT_repo_srv .
PUBLIC SECTION.
METHODS deserialize_checks
RETURNING
VALUE(rs_checks) TYPE zif_abapgit_definitions=>ty_deserialize_checks
RAISING
zcx_abapgit_exception .
METHODS delete_checks
RETURNING
VALUE(rs_checks) TYPE zif_abapgit_definitions=>ty_delete_checks
RAISING
zcx_abapgit_exception .
METHODS constructor
IMPORTING
!is_data TYPE zif_abapgit_persistence=>ty_repo .
METHODS get_key
RETURNING
VALUE(rv_key) TYPE zif_abapgit_persistence=>ty_value .
METHODS get_name
RETURNING
VALUE(rv_name) TYPE string
RAISING
zcx_abapgit_exception .
METHODS get_files_local
IMPORTING
!io_log TYPE REF TO zcl_abapgit_log OPTIONAL
!it_filter TYPE zif_abapgit_definitions=>ty_tadir_tt OPTIONAL
RETURNING
VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_files_item_tt
RAISING
zcx_abapgit_exception .
METHODS get_local_checksums
RETURNING
VALUE(rt_checksums) TYPE zif_abapgit_persistence=>ty_local_checksum_tt .
METHODS get_local_checksums_per_file
RETURNING
VALUE(rt_checksums) TYPE zif_abapgit_definitions=>ty_file_signatures_tt .
METHODS get_files_remote
RETURNING
VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_files_tt
RAISING
zcx_abapgit_exception .
METHODS get_package
RETURNING
VALUE(rv_package) TYPE zif_abapgit_persistence=>ty_repo-package .
METHODS delete
RAISING
zcx_abapgit_exception .
METHODS get_dot_abapgit
RETURNING
VALUE(ro_dot_abapgit) TYPE REF TO zcl_abapgit_dot_abapgit .
METHODS set_dot_abapgit
IMPORTING
!io_dot_abapgit TYPE REF TO zcl_abapgit_dot_abapgit
RAISING
zcx_abapgit_exception .
METHODS deserialize
IMPORTING
!is_checks TYPE zif_abapgit_definitions=>ty_deserialize_checks
RAISING
zcx_abapgit_exception .
METHODS refresh
IMPORTING
!iv_drop_cache TYPE abap_bool DEFAULT abap_false
RAISING
zcx_abapgit_exception .
METHODS update_local_checksums
IMPORTING
!it_files TYPE zif_abapgit_definitions=>ty_file_signatures_tt
RAISING
zcx_abapgit_exception .
METHODS rebuild_local_checksums
RAISING
zcx_abapgit_exception .
METHODS find_remote_dot_abapgit
RETURNING
VALUE(ro_dot) TYPE REF TO zcl_abapgit_dot_abapgit
RAISING
zcx_abapgit_exception .
METHODS is_offline
RETURNING
VALUE(rv_offline) TYPE abap_bool
RAISING
zcx_abapgit_exception .
METHODS set_files_remote
IMPORTING
!it_files TYPE zif_abapgit_definitions=>ty_files_tt
RAISING
zcx_abapgit_exception .
METHODS get_local_settings
RETURNING
VALUE(rs_settings) TYPE zif_abapgit_persistence=>ty_repo-local_settings .
METHODS set_local_settings
IMPORTING
!is_settings TYPE zif_abapgit_persistence=>ty_repo-local_settings
RAISING
zcx_abapgit_exception .
METHODS run_code_inspector
RETURNING
VALUE(rt_list) TYPE scit_alvlist
RAISING
zcx_abapgit_exception .
PROTECTED SECTION.
DATA mt_local TYPE zif_abapgit_definitions=>ty_files_item_tt .
DATA mt_remote TYPE zif_abapgit_definitions=>ty_files_tt .
DATA mv_do_local_refresh TYPE abap_bool .
DATA mv_last_serialization TYPE timestamp .
DATA ms_data TYPE zif_abapgit_persistence=>ty_repo .
DATA mv_code_inspector_successful TYPE abap_bool .
METHODS set
IMPORTING
!it_checksums TYPE zif_abapgit_persistence=>ty_local_checksum_tt OPTIONAL
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url OPTIONAL
!iv_branch_name TYPE zif_abapgit_persistence=>ty_repo-branch_name OPTIONAL
!iv_head_branch TYPE zif_abapgit_persistence=>ty_repo-head_branch OPTIONAL
!iv_offline TYPE zif_abapgit_persistence=>ty_repo-offline OPTIONAL
!is_dot_abapgit TYPE zif_abapgit_persistence=>ty_repo-dot_abapgit OPTIONAL
!is_local_settings TYPE zif_abapgit_persistence=>ty_repo-local_settings OPTIONAL
!iv_deserialized_at TYPE zif_abapgit_persistence=>ty_repo-deserialized_at OPTIONAL
!iv_deserialized_by TYPE zif_abapgit_persistence=>ty_repo-deserialized_by OPTIONAL
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
METHODS:
update_last_deserialize
RAISING
zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_repo_content_list DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo.
METHODS list
IMPORTING iv_path TYPE string
iv_by_folders TYPE abap_bool
iv_changes_only TYPE abap_bool
RETURNING VALUE(rt_repo_items) TYPE zif_abapgit_definitions=>tt_repo_items
RAISING zcx_abapgit_exception.
METHODS get_log
RETURNING VALUE(ro_log) TYPE REF TO zcl_abapgit_log.
PRIVATE SECTION.
CONSTANTS: BEGIN OF c_sortkey,
default TYPE i VALUE 9999,
parent_dir TYPE i VALUE 0,
dir TYPE i VALUE 1,
orphan TYPE i VALUE 2,
changed TYPE i VALUE 3,
END OF c_sortkey.
DATA: mo_repo TYPE REF TO zcl_abapgit_repo,
mo_log TYPE REF TO zcl_abapgit_log.
METHODS build_repo_items_offline
RETURNING VALUE(rt_repo_items) TYPE zif_abapgit_definitions=>tt_repo_items
RAISING zcx_abapgit_exception.
METHODS build_repo_items_online
RETURNING VALUE(rt_repo_items) TYPE zif_abapgit_definitions=>tt_repo_items
RAISING zcx_abapgit_exception.
METHODS build_folders
IMPORTING iv_cur_dir TYPE string
CHANGING ct_repo_items TYPE zif_abapgit_definitions=>tt_repo_items
RAISING zcx_abapgit_exception.
METHODS filter_changes
CHANGING ct_repo_items TYPE zif_abapgit_definitions=>tt_repo_items.
ENDCLASS.
CLASS zcl_abapgit_repo_offline DEFINITION
INHERITING FROM zcl_abapgit_repo
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
PROTECTED SECTION.
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_repo_online DEFINITION
INHERITING FROM zcl_abapgit_repo
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
INTERFACES zif_abapgit_git_operations .
ALIASES create_branch
FOR zif_abapgit_git_operations~create_branch .
ALIASES push
FOR zif_abapgit_git_operations~push .
METHODS constructor
IMPORTING
!is_data TYPE zif_abapgit_persistence=>ty_repo
RAISING
zcx_abapgit_exception .
METHODS get_url
RETURNING
VALUE(rv_url) TYPE zif_abapgit_persistence=>ty_repo-url .
METHODS get_branch_name
RETURNING
VALUE(rv_name) TYPE zif_abapgit_persistence=>ty_repo-branch_name .
METHODS set_url
IMPORTING
!iv_url TYPE zif_abapgit_persistence=>ty_repo-url
RAISING
zcx_abapgit_exception .
METHODS set_branch_name
IMPORTING
!iv_branch_name TYPE zif_abapgit_persistence=>ty_repo-branch_name
RAISING
zcx_abapgit_exception .
METHODS get_sha1_remote
RETURNING
VALUE(rv_sha1) TYPE zif_abapgit_definitions=>ty_sha1
RAISING
zcx_abapgit_exception .
METHODS get_objects
RETURNING
VALUE(rt_objects) TYPE zif_abapgit_definitions=>ty_objects_tt
RAISING
zcx_abapgit_exception .
METHODS status
IMPORTING
!io_log TYPE REF TO zcl_abapgit_log OPTIONAL
RETURNING
VALUE(rt_results) TYPE zif_abapgit_definitions=>ty_results_tt
RAISING
zcx_abapgit_exception .
METHODS get_unnecessary_local_objs
RETURNING
VALUE(rt_unnecessary_local_objects) TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
METHODS deserialize
REDEFINITION .
METHODS get_files_remote
REDEFINITION .
METHODS rebuild_local_checksums
REDEFINITION .
METHODS refresh
REDEFINITION .
PRIVATE SECTION.
DATA mt_objects TYPE zif_abapgit_definitions=>ty_objects_tt .
DATA mv_branch TYPE zif_abapgit_definitions=>ty_sha1 .
DATA mv_initialized TYPE abap_bool .
DATA mt_status TYPE zif_abapgit_definitions=>ty_results_tt .
METHODS reset_status .
METHODS initialize
RAISING
zcx_abapgit_exception .
METHODS handle_stage_ignore
IMPORTING
!io_stage TYPE REF TO zcl_abapgit_stage
RAISING
zcx_abapgit_exception .
METHODS set_objects
IMPORTING
!it_objects TYPE zif_abapgit_definitions=>ty_objects_tt
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_repo_srv DEFINITION
FINAL
CREATE PRIVATE .
PUBLIC SECTION.
INTERFACES zif_abapgit_repo_srv .
CLASS-METHODS get_instance
RETURNING
VALUE(ri_srv) TYPE REF TO zif_abapgit_repo_srv .
PRIVATE SECTION.
ALIASES delete
FOR zif_abapgit_repo_srv~delete .
ALIASES get
FOR zif_abapgit_repo_srv~get .
ALIASES list
FOR zif_abapgit_repo_srv~list .
ALIASES validate_package
FOR zif_abapgit_repo_srv~validate_package .
CLASS-DATA gi_ref TYPE REF TO zif_abapgit_repo_srv .
DATA mv_init TYPE abap_bool VALUE abap_false ##NO_TEXT.
DATA mt_list TYPE zif_abapgit_definitions=>ty_repo_ref_tt .
METHODS refresh
RAISING
zcx_abapgit_exception .
METHODS constructor .
METHODS is_sap_object_allowed
RETURNING
VALUE(rv_allowed) TYPE abap_bool .
METHODS add
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
RAISING
zcx_abapgit_exception .
METHODS validate_sub_super_packages
IMPORTING
!iv_package TYPE devclass
!it_repos TYPE zif_abapgit_persistence=>tt_repo
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_sap_package DEFINITION CREATE PRIVATE
FRIENDS ZCL_ABAPGIT_factory.
PUBLIC SECTION.
METHODS:
constructor
IMPORTING iv_package TYPE devclass.
INTERFACES: zif_abapgit_sap_package.
PRIVATE SECTION.
DATA: mv_package TYPE devclass.
ALIASES:
create FOR zif_abapgit_sap_package~create,
create_local FOR zif_abapgit_sap_package~create_local.
ENDCLASS.
CLASS zcl_abapgit_settings DEFINITION CREATE PUBLIC.
PUBLIC SECTION.
CONSTANTS: c_commitmsg_comment_length_dft TYPE i VALUE 50.
CONSTANTS: c_commitmsg_body_size_dft TYPE i VALUE 72.
METHODS:
set_proxy_url
IMPORTING
iv_url TYPE string,
set_proxy_port
IMPORTING
iv_port TYPE string,
set_proxy_authentication
IMPORTING
iv_auth TYPE abap_bool,
get_proxy_url
RETURNING
VALUE(rv_proxy_url) TYPE string,
get_proxy_port
RETURNING
VALUE(rv_port) TYPE string,
get_proxy_authentication
RETURNING
VALUE(rv_auth) TYPE abap_bool,
set_run_critical_tests
IMPORTING
iv_run TYPE abap_bool,
get_run_critical_tests
RETURNING
VALUE(rv_run) TYPE abap_bool,
set_experimental_features
IMPORTING
iv_run TYPE abap_bool,
get_experimental_features
RETURNING
VALUE(rv_run) TYPE abap_bool,
set_max_lines
IMPORTING iv_lines TYPE i,
get_max_lines
RETURNING
VALUE(rv_lines) TYPE i,
set_adt_jump_enanbled
IMPORTING
iv_adt_jump_enabled TYPE abap_bool,
get_adt_jump_enabled
RETURNING
VALUE(rv_adt_jump_enabled) TYPE abap_bool,
set_commitmsg_comment_length
IMPORTING
iv_length TYPE i,
get_commitmsg_comment_length
RETURNING
VALUE(rv_length) TYPE i,
set_commitmsg_body_size
IMPORTING
iv_length TYPE i,
get_commitmsg_body_size
RETURNING
VALUE(rv_length) TYPE i,
get_settings_xml
RETURNING
VALUE(rv_settings_xml) TYPE string
RAISING
zcx_abapgit_exception,
get_user_settings
RETURNING
VALUE(rs_settings) TYPE zif_abapgit_definitions=>ty_s_user_settings
RAISING
zcx_abapgit_exception,
set_xml_settings
IMPORTING
iv_settings_xml TYPE string
RAISING
zcx_abapgit_exception,
set_defaults,
set_user_settings
IMPORTING
is_user_settings TYPE zif_abapgit_definitions=>ty_s_user_settings,
get_show_default_repo
RETURNING
VALUE(rv_show_default_repo) TYPE abap_bool,
set_show_default_repo
IMPORTING
iv_show_default_repo TYPE abap_bool,
set_link_hints_enabled
IMPORTING
iv_link_hints_enabled TYPE abap_bool,
get_link_hints_enabled
RETURNING
VALUE(rv_link_hints_enabled) TYPE abap_bool
RAISING
zcx_abapgit_exception,
set_link_hint_key
IMPORTING
iv_link_hint_key TYPE char01,
get_link_hint_key
RETURNING
VALUE(rv_link_hint_key) TYPE char01,
get_link_hint_background_color
RETURNING
VALUE(rv_background_color) TYPE string,
set_link_hint_background_color
IMPORTING
iv_background_color TYPE string,
set_hotkeys
IMPORTING
it_hotkeys TYPE zif_abapgit_definitions=>tty_hotkey,
get_hotkeys
RETURNING
VALUE(rt_hotkeys) TYPE zif_abapgit_definitions=>tty_hotkey
RAISING
zcx_abapgit_exception.
PRIVATE SECTION.
TYPES: BEGIN OF ty_s_settings,
proxy_url TYPE string,
proxy_port TYPE string,
proxy_auth TYPE string,
run_critical_tests TYPE abap_bool,
experimental_features TYPE abap_bool,
commitmsg_comment_length TYPE i,
commitmsg_body_size TYPE i,
END OF ty_s_settings.
DATA: ms_settings TYPE ty_s_settings,
ms_user_settings TYPE zif_abapgit_definitions=>ty_s_user_settings.
METHODS:
set_default_link_hint_key,
set_default_link_hint_bg_color.
ENDCLASS.
CLASS zcl_abapgit_skip_objects DEFINITION FINAL CREATE PUBLIC.
PUBLIC SECTION.
METHODS:
skip_sadl_generated_objects
IMPORTING
it_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt
io_log TYPE REF TO zcl_abapgit_log OPTIONAL
RETURNING
VALUE(rt_tadir) TYPE zif_abapgit_definitions=>ty_tadir_tt.
PRIVATE SECTION.
METHODS:
has_sadl_superclass
IMPORTING
is_class TYPE zif_abapgit_definitions=>ty_tadir
RETURNING
VALUE(rv_return) TYPE abap_bool.
ENDCLASS.
CLASS zcl_abapgit_stage DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
ty_method TYPE c LENGTH 1 .
TYPES:
BEGIN OF ty_stage,
file TYPE zif_abapgit_definitions=>ty_file,
method TYPE ty_method,
END OF ty_stage .
TYPES:
ty_stage_tt TYPE SORTED TABLE OF ty_stage
WITH UNIQUE KEY file-path file-filename .
CONSTANTS:
BEGIN OF c_method,
add TYPE ty_method VALUE 'A',
rm TYPE ty_method VALUE 'R',
ignore TYPE ty_method VALUE 'I',
skip TYPE ty_method VALUE '?',
END OF c_method .
CLASS-METHODS method_description
IMPORTING
!iv_method TYPE ty_method
RETURNING
VALUE(rv_description) TYPE string
RAISING
zcx_abapgit_exception .
METHODS constructor
IMPORTING
!iv_merge_source TYPE zif_abapgit_definitions=>ty_sha1 OPTIONAL .
METHODS add
IMPORTING
!iv_path TYPE zif_abapgit_definitions=>ty_file-path
!iv_filename TYPE zif_abapgit_definitions=>ty_file-filename
!iv_data TYPE xstring
RAISING
zcx_abapgit_exception .
METHODS reset
IMPORTING
!iv_path TYPE zif_abapgit_definitions=>ty_file-path
!iv_filename TYPE zif_abapgit_definitions=>ty_file-filename
RAISING
zcx_abapgit_exception .
METHODS rm
IMPORTING
!iv_path TYPE zif_abapgit_definitions=>ty_file-path
!iv_filename TYPE zif_abapgit_definitions=>ty_file-filename
RAISING
zcx_abapgit_exception .
METHODS ignore
IMPORTING
!iv_path TYPE zif_abapgit_definitions=>ty_file-path
!iv_filename TYPE zif_abapgit_definitions=>ty_file-filename
RAISING
zcx_abapgit_exception .
METHODS get_merge_source
RETURNING
VALUE(rv_source) TYPE zif_abapgit_definitions=>ty_sha1 .
METHODS count
RETURNING
VALUE(rv_count) TYPE i .
METHODS get_all
RETURNING
VALUE(rt_stage) TYPE ty_stage_tt .
PRIVATE SECTION.
DATA mt_stage TYPE ty_stage_tt .
DATA mv_merge_source TYPE zif_abapgit_definitions=>ty_sha1 .
METHODS append
IMPORTING
!iv_path TYPE zif_abapgit_definitions=>ty_file-path
!iv_filename TYPE zif_abapgit_definitions=>ty_file-filename
!iv_method TYPE ty_method
!iv_data TYPE xstring OPTIONAL
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_stage_logic DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS get
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo_online
RETURNING
VALUE(rs_files) TYPE zif_abapgit_definitions=>ty_stage_files
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
CLASS-METHODS:
remove_ignored
IMPORTING io_repo TYPE REF TO zcl_abapgit_repo_online
CHANGING cs_files TYPE zif_abapgit_definitions=>ty_stage_files,
remove_identical
CHANGING cs_files TYPE zif_abapgit_definitions=>ty_stage_files.
ENDCLASS.
CLASS zcl_abapgit_syntax_check DEFINITION
INHERITING FROM zcl_abapgit_code_inspector
FRIENDS ZCL_ABAPGIT_factory.
PROTECTED SECTION.
METHODS:
create_variant REDEFINITION.
ENDCLASS.
CLASS zcl_abapgit_tadir DEFINITION
FINAL
CREATE PRIVATE
FRIENDS ZCL_ABAPGIT_factory .
PUBLIC SECTION.
INTERFACES zif_abapgit_tadir .
PRIVATE SECTION.
METHODS exists
IMPORTING
!is_item TYPE zif_abapgit_definitions=>ty_item
RETURNING
VALUE(rv_exists) TYPE abap_bool .
METHODS check_exists
IMPORTING
!it_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt
RETURNING
VALUE(rt_tadir) TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
METHODS build
IMPORTING
!iv_package TYPE tadir-devclass
!iv_top TYPE tadir-devclass
!io_dot TYPE REF TO zcl_abapgit_dot_abapgit
!iv_ignore_subpackages TYPE abap_bool DEFAULT abap_false
!iv_only_local_objects TYPE abap_bool
!io_log TYPE REF TO zcl_abapgit_log OPTIONAL
!io_folder_logic TYPE REF TO zcl_abapgit_folder_logic OPTIONAL
RETURNING
VALUE(rt_tadir) TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_transport DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS zip
RAISING
zcx_abapgit_exception .
CLASS-METHODS to_tadir
IMPORTING
!it_transport_headers TYPE trwbo_request_headers
RETURNING
VALUE(rt_tadir) TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
CLASS-METHODS read_requests
IMPORTING
!it_trkorr TYPE trwbo_request_headers
RETURNING
VALUE(rt_requests) TYPE trwbo_requests
RAISING
zcx_abapgit_exception .
CLASS-METHODS find_top_package
IMPORTING
!it_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt
RETURNING
VALUE(rv_package) TYPE devclass .
CLASS-METHODS resolve
IMPORTING
!it_requests TYPE trwbo_requests
RETURNING
VALUE(rt_tadir) TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
ENDCLASS.
CLASS zcl_abapgit_transport_2_branch DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS create
IMPORTING
!io_repository TYPE REF TO zcl_abapgit_repo_online
!is_transport_to_branch TYPE zif_abapgit_definitions=>ty_transport_to_branch
!it_transport_objects TYPE zif_abapgit_definitions=>ty_tadir_tt
RAISING
zcx_abapgit_exception .
PROTECTED SECTION.
METHODS generate_commit_message
IMPORTING
!is_transport_to_branch TYPE zif_abapgit_definitions=>ty_transport_to_branch
RETURNING
VALUE(rs_comment) TYPE zif_abapgit_definitions=>ty_comment .
METHODS stage_transport_objects
IMPORTING
!it_transport_objects TYPE zif_abapgit_definitions=>ty_tadir_tt
!io_stage TYPE REF TO zcl_abapgit_stage
!is_stage_objects TYPE zif_abapgit_definitions=>ty_stage_files
!it_object_statuses TYPE zif_abapgit_definitions=>ty_results_tt
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
ENDCLASS.
CLASS zcl_abapgit_transport_objects DEFINITION
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!it_transport_objects TYPE zif_abapgit_definitions=>ty_tadir_tt .
METHODS to_stage
IMPORTING
!io_stage TYPE REF TO zcl_abapgit_stage
!is_stage_objects TYPE zif_abapgit_definitions=>ty_stage_files
!it_object_statuses TYPE zif_abapgit_definitions=>ty_results_tt
RAISING
zcx_abapgit_exception .
PRIVATE SECTION.
DATA mt_transport_objects TYPE zif_abapgit_definitions=>ty_tadir_tt .
ENDCLASS.
CLASS zcl_abapgit_zip DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS import
IMPORTING
!iv_key TYPE zif_abapgit_persistence=>ty_value
RAISING
zcx_abapgit_exception .
CLASS-METHODS export
IMPORTING
!io_repo TYPE REF TO zcl_abapgit_repo
!it_filter TYPE zif_abapgit_definitions=>ty_tadir_tt OPTIONAL
RAISING
zcx_abapgit_exception .
CLASS-METHODS export_package
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
CLASS-METHODS export_object
RAISING
zcx_abapgit_exception
zcx_abapgit_cancel .
PRIVATE SECTION.
CLASS-METHODS file_upload
RETURNING VALUE(rv_xstr) TYPE xstring
RAISING zcx_abapgit_exception.
CLASS-METHODS unzip_file
IMPORTING iv_xstr TYPE xstring
RETURNING VALUE(rt_files) TYPE zif_abapgit_definitions=>ty_files_tt
RAISING zcx_abapgit_exception.
CLASS-METHODS normalize_path
CHANGING ct_files TYPE zif_abapgit_definitions=>ty_files_tt
RAISING zcx_abapgit_exception.
CLASS-METHODS filename
IMPORTING iv_str TYPE string
EXPORTING ev_path TYPE string
ev_filename TYPE string
RAISING zcx_abapgit_exception.
CLASS-METHODS file_download
IMPORTING iv_package TYPE devclass
iv_xstr TYPE xstring
RAISING zcx_abapgit_exception.
CLASS-METHODS encode_files
IMPORTING it_files TYPE zif_abapgit_definitions=>ty_files_item_tt
RETURNING VALUE(rv_xstr) TYPE xstring
RAISING zcx_abapgit_exception.
ENDCLASS.
CLASS zcl_abapgit_zlib DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
TYPES:
BEGIN OF ty_decompress,
raw TYPE xstring,
compressed_len TYPE i,
END OF ty_decompress .
CLASS-METHODS decompress
IMPORTING
!iv_compressed TYPE xsequence
RETURNING
VALUE(rs_data) TYPE ty_decompress .
PRIVATE SECTION.
CONSTANTS: c_maxdcodes TYPE i VALUE 30.
CLASS-DATA: gv_out TYPE xstring,
go_lencode TYPE REF TO zcl_abapgit_zlib_huffman,
go_distcode TYPE REF TO zcl_abapgit_zlib_huffman,
go_stream TYPE REF TO zcl_abapgit_zlib_stream.
TYPES: BEGIN OF ty_pair,
length TYPE i,
distance TYPE i,
END OF ty_pair.
CLASS-METHODS:
decode
IMPORTING io_huffman TYPE REF TO zcl_abapgit_zlib_huffman
RETURNING VALUE(rv_symbol) TYPE i,
map_length
IMPORTING iv_code TYPE i
RETURNING VALUE(rv_length) TYPE i,
map_distance
IMPORTING iv_code TYPE i
RETURNING VALUE(rv_distance) TYPE i,
dynamic,
fixed,
read_pair
IMPORTING iv_length TYPE i
RETURNING VALUE(rs_pair) TYPE ty_pair,
copy_out
IMPORTING is_pair TYPE ty_pair.
ENDCLASS.
CLASS zcl_abapgit_zlib_convert DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
CLASS-METHODS hex_to_bits
IMPORTING
!iv_hex TYPE xsequence
RETURNING
VALUE(rv_bits) TYPE string .
CLASS-METHODS bits_to_int
IMPORTING
!iv_bits TYPE clike
RETURNING
VALUE(rv_int) TYPE i .
CLASS-METHODS int_to_hex
IMPORTING
!iv_int TYPE i
RETURNING
VALUE(rv_hex) TYPE xstring .
ENDCLASS.
CLASS zcl_abapgit_zlib_huffman DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
TYPES: ty_lengths TYPE STANDARD TABLE OF i WITH DEFAULT KEY.
CONSTANTS: c_maxbits TYPE i VALUE 15.
METHODS:
constructor
IMPORTING it_lengths TYPE ty_lengths,
get_count
IMPORTING iv_index TYPE i
RETURNING VALUE(rv_value) TYPE i,
get_symbol
IMPORTING iv_index TYPE i
RETURNING VALUE(rv_value) TYPE i.
PRIVATE SECTION.
DATA: mt_count TYPE STANDARD TABLE OF i WITH DEFAULT KEY,
mt_symbol TYPE STANDARD TABLE OF i WITH DEFAULT KEY.
ENDCLASS.
CLASS zcl_abapgit_zlib_stream DEFINITION
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!iv_data TYPE xstring .
METHODS take_bits
IMPORTING
!iv_length TYPE i
RETURNING
VALUE(rv_bits) TYPE string .
METHODS take_int
IMPORTING
!iv_length TYPE i
RETURNING
VALUE(rv_int) TYPE i .
METHODS remaining
RETURNING
VALUE(rv_length) TYPE i .
PRIVATE SECTION.
DATA: mv_compressed TYPE xstring,
mv_bits TYPE string.
ENDCLASS.
CLASS ZCL_ABAPGIT_ZLIB_STREAM IMPLEMENTATION.
METHOD constructor.
mv_compressed = iv_data.
ENDMETHOD.
METHOD remaining.
rv_length = xstrlen( mv_compressed ) + 1.
ENDMETHOD.
METHOD take_bits.
DATA: lv_left TYPE i,
lv_index TYPE i,
lv_x TYPE x LENGTH 1.
WHILE strlen( rv_bits ) < iv_length.
IF mv_bits IS INITIAL.
lv_x = mv_compressed(1).
mv_bits = zcl_abapgit_zlib_convert=>hex_to_bits( lv_x ).
mv_compressed = mv_compressed+1.
ENDIF.
lv_left = iv_length - strlen( rv_bits ).
IF lv_left >= strlen( mv_bits ).
CONCATENATE mv_bits rv_bits INTO rv_bits.
CLEAR mv_bits.
ELSE.
lv_index = strlen( mv_bits ) - lv_left.
CONCATENATE mv_bits+lv_index(lv_left) rv_bits INTO rv_bits.
mv_bits = mv_bits(lv_index).
ENDIF.
ENDWHILE.
ENDMETHOD.
METHOD take_int.
rv_int = zcl_abapgit_zlib_convert=>bits_to_int( take_bits( iv_length ) ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_ZLIB_HUFFMAN IMPLEMENTATION.
METHOD constructor.
DATA: lv_index TYPE i,
lt_offset TYPE TABLE OF i,
lv_length LIKE LINE OF it_lengths,
lv_prev TYPE i,
lv_count LIKE LINE OF mt_count.
FIELD-SYMBOLS: <lv_offset> LIKE LINE OF lt_offset,
<lv_symbol> LIKE LINE OF mt_symbol,
<lv_i> LIKE LINE OF it_lengths.
DO c_maxbits TIMES.
APPEND 0 TO mt_count.
ENDDO.
LOOP AT it_lengths INTO lv_index.
IF lv_index = 0.
CONTINUE.
ENDIF.
READ TABLE mt_count INDEX lv_index ASSIGNING <lv_i>.
ASSERT sy-subrc = 0.
<lv_i> = <lv_i> + 1.
ENDLOOP.
APPEND 0 TO lt_offset.
DO c_maxbits - 1 TIMES.
READ TABLE mt_count INDEX sy-index INTO lv_count.
ASSERT sy-subrc = 0.
lv_prev = lv_prev + lv_count.
APPEND lv_prev TO lt_offset.
ENDDO.
DO lines( it_lengths ) TIMES.
APPEND 0 TO mt_symbol.
ENDDO.
DO lines( it_lengths ) TIMES.
lv_index = sy-index.
READ TABLE it_lengths INDEX lv_index INTO lv_length.
ASSERT sy-subrc = 0.
IF lv_length = 0.
CONTINUE.
ENDIF.
READ TABLE lt_offset INDEX lv_length ASSIGNING <lv_offset>.
ASSERT sy-subrc = 0.
READ TABLE mt_symbol INDEX <lv_offset> + 1 ASSIGNING <lv_symbol>.
ASSERT sy-subrc = 0.
<lv_symbol> = lv_index - 1.
<lv_offset> = <lv_offset> + 1.
ENDDO.
ENDMETHOD.
METHOD get_count.
READ TABLE mt_count INDEX iv_index INTO rv_value. "#EC CI_SUBRC
ENDMETHOD.
METHOD get_symbol.
READ TABLE mt_symbol INDEX iv_index INTO rv_value. "#EC CI_SUBRC
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_ZLIB_CONVERT IMPLEMENTATION.
METHOD bits_to_int.
DATA: lv_c TYPE c LENGTH 1,
lv_bits TYPE string.
lv_bits = iv_bits.
WHILE NOT lv_bits IS INITIAL.
lv_c = lv_bits.
rv_int = rv_int * 2.
rv_int = rv_int + lv_c.
lv_bits = lv_bits+1.
ENDWHILE.
ENDMETHOD.
METHOD hex_to_bits.
DATA: lv_x TYPE x LENGTH 1,
lv_c TYPE c LENGTH 1,
lv_bit TYPE i,
lv_hex TYPE xstring.
lv_hex = iv_hex.
WHILE NOT lv_hex IS INITIAL.
lv_x = lv_hex.
DO 8 TIMES.
lv_bit = sy-index.
GET BIT lv_bit OF lv_x INTO lv_c.
CONCATENATE rv_bits lv_c INTO rv_bits.
ENDDO.
lv_hex = lv_hex+1.
ENDWHILE.
ENDMETHOD.
METHOD int_to_hex.
DATA: lv_x TYPE x.
lv_x = iv_int.
rv_hex = lv_x.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_ZLIB IMPLEMENTATION.
METHOD copy_out.
DATA: lv_distance TYPE i,
lv_index TYPE i,
lv_x TYPE x LENGTH 1.
lv_distance = xstrlen( gv_out ) - is_pair-distance.
DO is_pair-length TIMES.
lv_index = sy-index - 1 + lv_distance.
lv_x = gv_out+lv_index(1).
CONCATENATE gv_out lv_x INTO gv_out IN BYTE MODE.
ENDDO.
ENDMETHOD.
METHOD decode.
DATA: lv_bit TYPE c LENGTH 1,
lv_len TYPE i,
lv_count TYPE i,
lv_code TYPE i,
lv_index TYPE i,
lv_first TYPE i,
lv_bits TYPE string.
DO zcl_abapgit_zlib_huffman=>c_maxbits TIMES.
lv_len = sy-index.
lv_bit = go_stream->take_bits( 1 ).
CONCATENATE lv_bits lv_bit INTO lv_bits.
lv_code = zcl_abapgit_zlib_convert=>bits_to_int( lv_bits ).
lv_count = io_huffman->get_count( lv_len ).
IF lv_code - lv_count < lv_first.
rv_symbol = io_huffman->get_symbol( lv_index + lv_code - lv_first + 1 ).
RETURN.
ENDIF.
lv_index = lv_index + lv_count.
lv_first = lv_first + lv_count.
lv_first = lv_first * 2.
ENDDO.
ENDMETHOD.
METHOD decompress.
DATA: lv_x TYPE x LENGTH 1,
lv_symbol TYPE i,
lv_bfinal TYPE c LENGTH 1,
lv_btype TYPE c LENGTH 2.
IF iv_compressed IS INITIAL.
RETURN.
ENDIF.
CLEAR gv_out.
CREATE OBJECT go_stream
EXPORTING
iv_data = iv_compressed.
DO.
lv_bfinal = go_stream->take_bits( 1 ).
lv_btype = go_stream->take_bits( 2 ).
CASE lv_btype.
WHEN '01'.
fixed( ).
WHEN '10'.
dynamic( ).
WHEN OTHERS.
ASSERT 1 = 0.
ENDCASE.
DO.
lv_symbol = decode( go_lencode ).
IF lv_symbol < 256.
lv_x = zcl_abapgit_zlib_convert=>int_to_hex( lv_symbol ).
CONCATENATE gv_out lv_x INTO gv_out IN BYTE MODE.
ELSEIF lv_symbol = 256.
EXIT.
ELSE.
copy_out( read_pair( lv_symbol ) ).
ENDIF.
ENDDO.
IF lv_bfinal = '1'.
EXIT.
ENDIF.
ENDDO.
rs_data-raw = gv_out.
rs_data-compressed_len = xstrlen( iv_compressed ) - go_stream->remaining( ).
ENDMETHOD.
METHOD dynamic.
DATA: lv_nlen TYPE i,
lv_ndist TYPE i,
lv_ncode TYPE i,
lv_index TYPE i,
lv_length TYPE i,
lv_symbol TYPE i,
lt_order TYPE TABLE OF i,
lt_lengths TYPE zcl_abapgit_zlib_huffman=>ty_lengths,
lt_dists TYPE zcl_abapgit_zlib_huffman=>ty_lengths.
FIELD-SYMBOLS: <lv_length> LIKE LINE OF lt_lengths.
APPEND 16 TO lt_order.
APPEND 17 TO lt_order.
APPEND 18 TO lt_order.
APPEND 0 TO lt_order.
APPEND 8 TO lt_order.
APPEND 7 TO lt_order.
APPEND 9 TO lt_order.
APPEND 6 TO lt_order.
APPEND 10 TO lt_order.
APPEND 5 TO lt_order.
APPEND 11 TO lt_order.
APPEND 4 TO lt_order.
APPEND 12 TO lt_order.
APPEND 3 TO lt_order.
APPEND 13 TO lt_order.
APPEND 2 TO lt_order.
APPEND 14 TO lt_order.
APPEND 1 TO lt_order.
APPEND 15 TO lt_order.
lv_nlen = go_stream->take_int( 5 ) + 257.
lv_ndist = go_stream->take_int( 5 ) + 1.
lv_ncode = go_stream->take_int( 4 ) + 4.
DO 19 TIMES.
APPEND 0 TO lt_lengths.
ENDDO.
DO lv_ncode TIMES.
READ TABLE lt_order INDEX sy-index INTO lv_index.
ASSERT sy-subrc = 0.
lv_index = lv_index + 1.
READ TABLE lt_lengths INDEX lv_index ASSIGNING <lv_length>.
ASSERT sy-subrc = 0.
<lv_length> = go_stream->take_int( 3 ).
ENDDO.
CREATE OBJECT go_lencode
EXPORTING
it_lengths = lt_lengths.
CLEAR lt_lengths.
WHILE lines( lt_lengths ) < lv_nlen + lv_ndist.
lv_symbol = decode( go_lencode ).
IF lv_symbol < 16.
APPEND lv_symbol TO lt_lengths.
ELSE.
lv_length = 0.
IF lv_symbol = 16.
READ TABLE lt_lengths INDEX lines( lt_lengths ) INTO lv_length.
ASSERT sy-subrc = 0.
lv_symbol = go_stream->take_int( 2 ) + 3.
ELSEIF lv_symbol = 17.
lv_symbol = go_stream->take_int( 3 ) + 3.
ELSE.
lv_symbol = go_stream->take_int( 7 ) + 11.
ENDIF.
DO lv_symbol TIMES.
APPEND lv_length TO lt_lengths.
ENDDO.
ENDIF.
ENDWHILE.
lt_dists = lt_lengths.
DELETE lt_lengths FROM lv_nlen + 1.
DELETE lt_dists TO lv_nlen.
CREATE OBJECT go_lencode
EXPORTING
it_lengths = lt_lengths.
CREATE OBJECT go_distcode
EXPORTING
it_lengths = lt_dists.
ENDMETHOD.
METHOD fixed.
DATA: lt_lengths TYPE zcl_abapgit_zlib_huffman=>ty_lengths.
DO 144 TIMES.
APPEND 8 TO lt_lengths.
ENDDO.
DO 112 TIMES.
APPEND 9 TO lt_lengths.
ENDDO.
DO 24 TIMES.
APPEND 7 TO lt_lengths.
ENDDO.
DO 8 TIMES.
APPEND 8 TO lt_lengths.
ENDDO.
CREATE OBJECT go_lencode
EXPORTING
it_lengths = lt_lengths.
CLEAR lt_lengths.
DO c_maxdcodes TIMES.
APPEND 5 TO lt_lengths.
ENDDO.
CREATE OBJECT go_distcode
EXPORTING
it_lengths = lt_lengths.
ENDMETHOD.
METHOD map_distance.
DEFINE _distance.
rv_distance = go_stream->take_int( &1 ).
rv_distance = rv_distance + &2.
END-OF-DEFINITION.
CASE iv_code.
WHEN 0.
_distance 0 1.
WHEN 1.
_distance 0 2.
WHEN 2.
_distance 0 3.
WHEN 3.
_distance 0 4.
WHEN 4.
_distance 1 5.
WHEN 5.
_distance 1 7.
WHEN 6.
_distance 2 9.
WHEN 7.
_distance 2 13.
WHEN 8.
_distance 3 17.
WHEN 9.
_distance 3 25.
WHEN 10.
_distance 4 33.
WHEN 11.
_distance 4 49.
WHEN 12.
_distance 5 65.
WHEN 13.
_distance 5 97.
WHEN 14.
_distance 6 129.
WHEN 15.
_distance 6 193.
WHEN 16.
_distance 7 257.
WHEN 17.
_distance 7 385.
WHEN 18.
_distance 8 513.
WHEN 19.
_distance 8 769.
WHEN 20.
_distance 9 1025.
WHEN 21.
_distance 9 1537.
WHEN 22.
_distance 10 2049.
WHEN 23.
_distance 10 3073.
WHEN 24.
_distance 11 4097.
WHEN 25.
_distance 11 6145.
WHEN 26.
_distance 12 8193.
WHEN 27.
_distance 12 12289.
WHEN 28.
_distance 13 16385.
WHEN 29.
_distance 13 24577.
WHEN OTHERS.
ASSERT 1 = 0.
ENDCASE.
ENDMETHOD.
METHOD map_length.
DEFINE _length.
rv_length = go_stream->take_int( &1 ).
rv_length = rv_length + &2.
END-OF-DEFINITION.
CASE iv_code.
WHEN 257.
_length 0 3.
WHEN 258.
_length 0 4.
WHEN 259.
_length 0 5.
WHEN 260.
_length 0 6.
WHEN 261.
_length 0 7.
WHEN 262.
_length 0 8.
WHEN 263.
_length 0 9.
WHEN 264.
_length 0 10.
WHEN 265.
_length 1 11.
WHEN 266.
_length 1 13.
WHEN 267.
_length 1 15.
WHEN 268.
_length 1 17.
WHEN 269.
_length 2 19.
WHEN 270.
_length 2 23.
WHEN 271.
_length 2 27.
WHEN 272.
_length 2 31.
WHEN 273.
_length 3 35.
WHEN 274.
_length 3 43.
WHEN 275.
_length 3 51.
WHEN 276.
_length 3 59.
WHEN 277.
_length 4 67.
WHEN 278.
_length 4 83.
WHEN 279.
_length 4 99.
WHEN 280.
_length 4 115.
WHEN 281.
_length 5 131.
WHEN 282.
_length 5 163.
WHEN 283.
_length 5 195.
WHEN 284.
_length 5 227.
WHEN 285.
_length 0 258.
WHEN OTHERS.
ASSERT 1 = 0.
ENDCASE.
ENDMETHOD.
METHOD read_pair.
DATA: lv_symbol TYPE i.
rs_pair-length = map_length( iv_length ).
lv_symbol = decode( go_distcode ).
rs_pair-distance = map_distance( lv_symbol ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_ZIP IMPLEMENTATION.
METHOD encode_files.
DATA: lo_zip TYPE REF TO cl_abap_zip,
lv_filename TYPE string.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF it_files.
CREATE OBJECT lo_zip.
LOOP AT it_files ASSIGNING <ls_file>.
CONCATENATE <ls_file>-file-path+1 <ls_file>-file-filename INTO lv_filename.
lo_zip->add( name = lv_filename
content = <ls_file>-file-data ).
ENDLOOP.
rv_xstr = lo_zip->save( ).
ENDMETHOD. "encode_files
METHOD export.
DATA: lo_log TYPE REF TO zcl_abapgit_log,
lt_zip TYPE zif_abapgit_definitions=>ty_files_item_tt,
lv_package TYPE devclass.
CREATE OBJECT lo_log.
lv_package = io_repo->get_package( ).
IF zcl_abapgit_factory=>get_sap_package( lv_package )->exists( ) = abap_false.
zcx_abapgit_exception=>raise( |Package { lv_package } doesn't exist| ).
ENDIF.
lt_zip = io_repo->get_files_local( io_log = lo_log
it_filter = it_filter ).
IF lo_log->count( ) > 0.
lo_log->show( ).
ENDIF.
file_download( iv_package = io_repo->get_package( )
iv_xstr = encode_files( lt_zip ) ).
ENDMETHOD. "export_key
METHOD export_object.
DATA: ls_tadir TYPE zif_abapgit_definitions=>ty_tadir,
ls_item TYPE zif_abapgit_definitions=>ty_item,
lv_folder TYPE string,
lv_fullpath TYPE string,
lt_rawdata TYPE solix_tab,
lv_sep TYPE c LENGTH 1,
lt_files TYPE zif_abapgit_definitions=>ty_files_tt.
STATICS: sv_prev TYPE string.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF lt_files.
ls_tadir = zcl_abapgit_ui_factory=>get_popups( )->popup_object( ).
IF ls_tadir IS INITIAL.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
ls_item-obj_type = ls_tadir-object.
ls_item-obj_name = ls_tadir-obj_name.
lt_files = zcl_abapgit_objects=>serialize(
is_item = ls_item
iv_language = sy-langu ).
IF lines( lt_files ) = 0.
MESSAGE 'Empty' TYPE 'S'.
RETURN.
ENDIF.
cl_gui_frontend_services=>directory_browse(
EXPORTING
initial_folder = sv_prev
CHANGING
selected_folder = lv_folder ).
IF lv_folder IS INITIAL.
RETURN.
ENDIF.
sv_prev = lv_folder.
cl_gui_frontend_services=>get_file_separator(
CHANGING
file_separator = lv_sep ).
LOOP AT lt_files ASSIGNING <ls_file>.
CONCATENATE lv_folder lv_sep <ls_file>-filename INTO lv_fullpath.
lt_rawdata = cl_bcs_convert=>xstring_to_solix( <ls_file>-data ).
cl_gui_frontend_services=>gui_download(
EXPORTING
bin_filesize = xstrlen( <ls_file>-data )
filename = lv_fullpath
filetype = 'BIN'
CHANGING
data_tab = lt_rawdata
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6
header_not_allowed = 7
separator_not_allowed = 8
filesize_not_allowed = 9
header_too_long = 10
dp_error_create = 11
dp_error_send = 12
dp_error_write = 13
unknown_dp_error = 14
access_denied = 15
dp_out_of_memory = 16
disk_full = 17
dp_timeout = 18
file_not_found = 19
dataprovider_exception = 20
control_flush_error = 21
not_supported_by_gui = 22
error_no_gui = 23
OTHERS = 24 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from gui_download' ).
ENDIF.
ENDLOOP.
ENDMETHOD. "export_package
METHOD export_package.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_offline,
ls_data TYPE zif_abapgit_persistence=>ty_repo,
li_popups TYPE REF TO zif_abapgit_popups.
ls_data-key = 'DUMMY'.
ls_data-dot_abapgit = zcl_abapgit_dot_abapgit=>build_default( )->get_data( ).
li_popups = zcl_abapgit_ui_factory=>get_popups( ).
li_popups->popup_package_export(
IMPORTING
ev_package = ls_data-package
ev_folder_logic = ls_data-dot_abapgit-folder_logic ).
IF ls_data-package IS INITIAL.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
CREATE OBJECT lo_repo
EXPORTING
is_data = ls_data.
export( lo_repo ).
ENDMETHOD. "export_package
METHOD filename.
IF iv_str CA '/'.
FIND REGEX '(.*/)(.*)' IN iv_str
SUBMATCHES ev_path ev_filename.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Malformed path' ).
ENDIF.
IF ev_path <> '/'.
CONCATENATE '/' ev_path INTO ev_path.
ENDIF.
ELSE.
ev_path = '/'.
ev_filename = iv_str.
ENDIF.
TRANSLATE ev_filename TO LOWER CASE.
ENDMETHOD. "filename
METHOD file_download.
DATA: lt_rawdata TYPE solix_tab,
lv_action TYPE i,
lv_filename TYPE string,
lv_default TYPE string,
lv_path TYPE string,
lv_fullpath TYPE string,
lv_package TYPE devclass.
lv_package = iv_package.
TRANSLATE lv_package USING '/#'.
CONCATENATE lv_package '_' sy-datlo '_' sy-timlo INTO lv_default.
cl_gui_frontend_services=>file_save_dialog(
EXPORTING
window_title = 'Export ZIP'
default_extension = 'zip'
default_file_name = lv_default
CHANGING
filename = lv_filename
path = lv_path
fullpath = lv_fullpath
user_action = lv_action
EXCEPTIONS
cntl_error = 1
error_no_gui = 2
not_supported_by_gui = 3
OTHERS = 4 ). "#EC NOTEXT
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from file_save_dialog' ).
ENDIF.
IF lv_action = cl_gui_frontend_services=>action_cancel.
zcx_abapgit_exception=>raise( 'cancelled' ).
ENDIF.
lt_rawdata = cl_bcs_convert=>xstring_to_solix( iv_xstr ).
cl_gui_frontend_services=>gui_download(
EXPORTING
bin_filesize = xstrlen( iv_xstr )
filename = lv_fullpath
filetype = 'BIN'
CHANGING
data_tab = lt_rawdata
EXCEPTIONS
file_write_error = 1
no_batch = 2
gui_refuse_filetransfer = 3
invalid_type = 4
no_authority = 5
unknown_error = 6
header_not_allowed = 7
separator_not_allowed = 8
filesize_not_allowed = 9
header_too_long = 10
dp_error_create = 11
dp_error_send = 12
dp_error_write = 13
unknown_dp_error = 14
access_denied = 15
dp_out_of_memory = 16
disk_full = 17
dp_timeout = 18
file_not_found = 19
dataprovider_exception = 20
control_flush_error = 21
not_supported_by_gui = 22
error_no_gui = 23
OTHERS = 24 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from gui_download' ).
ENDIF.
ENDMETHOD. "file_download
METHOD file_upload.
DATA: lt_data TYPE TABLE OF x255,
lt_file_table TYPE filetable,
ls_file_table LIKE LINE OF lt_file_table,
lv_action TYPE i,
lv_string TYPE string,
lv_rc TYPE i,
lv_length TYPE i.
cl_gui_frontend_services=>file_open_dialog(
EXPORTING
window_title = 'Import ZIP'
default_filename = '*.zip'
CHANGING
file_table = lt_file_table
rc = lv_rc
user_action = lv_action
EXCEPTIONS
file_open_dialog_failed = 1
cntl_error = 2
error_no_gui = 3
not_supported_by_gui = 4
OTHERS = 5 ). "#EC NOTEXT
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from file_open_dialog' ).
ENDIF.
IF lv_action = cl_gui_frontend_services=>action_cancel.
zcx_abapgit_exception=>raise( 'cancelled' ).
ENDIF.
READ TABLE lt_file_table INDEX 1 INTO ls_file_table.
ASSERT sy-subrc = 0.
lv_string = ls_file_table-filename.
cl_gui_frontend_services=>gui_upload(
EXPORTING
filename = lv_string
filetype = 'BIN'
IMPORTING
filelength = lv_length
CHANGING
data_tab = lt_data
EXCEPTIONS
file_open_error = 1
file_read_error = 2
no_batch = 3
gui_refuse_filetransfer = 4
invalid_type = 5
no_authority = 6
unknown_error = 7
bad_data_format = 8
header_not_allowed = 9
separator_not_allowed = 10
header_too_long = 11
unknown_dp_error = 12
access_denied = 13
dp_out_of_memory = 14
disk_full = 15
dp_timeout = 16
not_supported_by_gui = 17
error_no_gui = 18
OTHERS = 19 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from gui_upload' ).
ENDIF.
CONCATENATE LINES OF lt_data INTO rv_xstr IN BYTE MODE.
rv_xstr = rv_xstr(lv_length).
ENDMETHOD. "file_upload
METHOD import.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_offline.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
lo_repo->set_files_remote( unzip_file( file_upload( ) ) ).
zcl_abapgit_services_repo=>gui_deserialize( lo_repo ).
ENDMETHOD. "import
METHOD normalize_path.
DATA: lt_split TYPE TABLE OF string,
lv_needed TYPE abap_bool,
lv_length TYPE i,
lv_split LIKE LINE OF lt_split.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF ct_files.
READ TABLE ct_files INDEX 1 ASSIGNING <ls_file>.
IF sy-subrc <> 0.
RETURN.
ENDIF.
SPLIT <ls_file>-path AT '/' INTO TABLE lt_split.
IF sy-subrc <> 0.
RETURN.
ENDIF.
READ TABLE lt_split INDEX 2 INTO lv_split.
IF sy-subrc <> 0 OR strlen( lv_split ) = 0.
RETURN.
ENDIF.
CONCATENATE '/' lv_split '/*' INTO lv_split.
lv_needed = abap_true.
LOOP AT ct_files ASSIGNING <ls_file>.
IF NOT <ls_file>-path CP lv_split.
lv_needed = abap_false.
EXIT. " current loop
ENDIF.
ENDLOOP.
IF lv_needed = abap_true.
lv_length = strlen( lv_split ) - 2.
LOOP AT ct_files ASSIGNING <ls_file>.
<ls_file>-path = <ls_file>-path+lv_length.
ENDLOOP.
ENDIF.
ENDMETHOD. "normalize_path
METHOD unzip_file.
DATA: lo_zip TYPE REF TO cl_abap_zip,
lv_data TYPE xstring.
FIELD-SYMBOLS: <ls_zipfile> TYPE cl_abap_zip=>t_file,
<ls_file> LIKE LINE OF rt_files.
CREATE OBJECT lo_zip.
lo_zip->load( EXPORTING
zip = iv_xstr
EXCEPTIONS
zip_parse_error = 1
OTHERS = 2 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from zip' ).
ENDIF.
LOOP AT lo_zip->files ASSIGNING <ls_zipfile>.
lo_zip->get(
EXPORTING
name = <ls_zipfile>-name
IMPORTING
content = lv_data
EXCEPTIONS
zip_index_error = 1
zip_decompression_error = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from zip get' ).
ENDIF.
APPEND INITIAL LINE TO rt_files ASSIGNING <ls_file>.
filename(
EXPORTING
iv_str = <ls_zipfile>-name
IMPORTING
ev_path = <ls_file>-path
ev_filename = <ls_file>-filename ).
<ls_file>-data = lv_data.
<ls_file>-sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>c_type-blob
iv_data = <ls_file>-data ).
ENDLOOP.
normalize_path( CHANGING ct_files = rt_files ).
ENDMETHOD. "decode_files
ENDCLASS.
CLASS ZCL_ABAPGIT_TRANSPORT_OBJECTS IMPLEMENTATION.
METHOD constructor.
mt_transport_objects = it_transport_objects.
ENDMETHOD.
METHOD to_stage.
DATA: ls_transport_object LIKE LINE OF mt_transport_objects,
ls_local_file TYPE zif_abapgit_definitions=>ty_file_item,
ls_object_status TYPE zif_abapgit_definitions=>ty_result.
LOOP AT mt_transport_objects INTO ls_transport_object.
LOOP AT it_object_statuses INTO ls_object_status
WHERE obj_name = ls_transport_object-obj_name
AND obj_type = ls_transport_object-object
AND NOT lstate IS INITIAL.
CASE ls_object_status-lstate.
WHEN zif_abapgit_definitions=>c_state-added OR zif_abapgit_definitions=>c_state-modified.
IF ls_transport_object-delflag = abap_true.
zcx_abapgit_exception=>raise( |Object { ls_transport_object-obj_name
} should be added/modified, but has deletion flag in transport| ).
ENDIF.
READ TABLE is_stage_objects-local
INTO ls_local_file
WITH KEY item-obj_name = ls_transport_object-obj_name
item-obj_type = ls_transport_object-object
file-filename = ls_object_status-filename.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Object { ls_transport_object-obj_name
} not found in the local repository files| ).
ENDIF.
io_stage->add(
iv_path = ls_local_file-file-path
iv_filename = ls_local_file-file-filename
iv_data = ls_local_file-file-data ).
WHEN zif_abapgit_definitions=>c_state-deleted.
IF ls_transport_object-delflag = abap_false.
zcx_abapgit_exception=>raise( |Object { ls_transport_object-obj_name
} should be removed, but has NO deletion flag in transport| ).
ENDIF.
io_stage->rm(
iv_path = ls_object_status-path
iv_filename = ls_object_status-filename ).
WHEN OTHERS.
ASSERT 0 = 1. "Unexpected state
ENDCASE.
ENDLOOP.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Object { ls_transport_object-obj_name
} not found in the local repository files| ).
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_TRANSPORT_2_BRANCH IMPLEMENTATION.
METHOD create.
DATA:
lv_branch_name TYPE string,
ls_comment TYPE zif_abapgit_definitions=>ty_comment,
lo_stage TYPE REF TO zcl_abapgit_stage,
ls_stage_objects TYPE zif_abapgit_definitions=>ty_stage_files,
lt_object_statuses TYPE zif_abapgit_definitions=>ty_results_tt.
lv_branch_name = zcl_abapgit_git_branch_list=>complete_heads_branch_name(
zcl_abapgit_git_branch_list=>normalize_branch_name( is_transport_to_branch-branch_name ) ).
io_repository->create_branch( lv_branch_name ).
CREATE OBJECT lo_stage.
ls_stage_objects = zcl_abapgit_stage_logic=>get( io_repository ).
lt_object_statuses = io_repository->status( ).
stage_transport_objects(
it_transport_objects = it_transport_objects
io_stage = lo_stage
is_stage_objects = ls_stage_objects
it_object_statuses = lt_object_statuses ).
ls_comment = generate_commit_message( is_transport_to_branch ).
io_repository->push( is_comment = ls_comment
io_stage = lo_stage ).
ENDMETHOD.
METHOD generate_commit_message.
rs_comment-committer-name = sy-uname.
rs_comment-committer-email = |{ rs_comment-committer-name }@localhost|.
rs_comment-comment = is_transport_to_branch-commit_text.
ENDMETHOD.
METHOD stage_transport_objects.
DATA lo_transport_objects TYPE REF TO zcl_abapgit_transport_objects.
CREATE OBJECT lo_transport_objects
EXPORTING
it_transport_objects = it_transport_objects.
lo_transport_objects->to_stage(
io_stage = io_stage
is_stage_objects = is_stage_objects
it_object_statuses = it_object_statuses ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_TRANSPORT IMPLEMENTATION.
METHOD find_top_package.
DATA: lt_obj TYPE zif_abapgit_sap_package=>ty_devclass_tt,
lt_super TYPE zif_abapgit_sap_package=>ty_devclass_tt,
lv_super LIKE LINE OF lt_super,
lv_index TYPE i.
FIELD-SYMBOLS: <ls_tadir> LIKE LINE OF it_tadir.
READ TABLE it_tadir INDEX 1 ASSIGNING <ls_tadir>.
ASSERT sy-subrc = 0.
lt_super = zcl_abapgit_factory=>get_sap_package( <ls_tadir>-devclass )->list_superpackages( ).
LOOP AT it_tadir ASSIGNING <ls_tadir>.
lt_obj = zcl_abapgit_factory=>get_sap_package( <ls_tadir>-devclass )->list_superpackages( ).
LOOP AT lt_super INTO lv_super.
lv_index = sy-tabix.
READ TABLE lt_obj FROM lv_super TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
DELETE lt_super INDEX lv_index.
ENDIF.
ENDLOOP.
ENDLOOP.
SORT lt_super.
READ TABLE lt_super INDEX 1 INTO rv_package.
ENDMETHOD.
METHOD read_requests.
DATA lt_requests LIKE rt_requests.
FIELD-SYMBOLS <ls_trkorr> LIKE LINE OF it_trkorr.
LOOP AT it_trkorr ASSIGNING <ls_trkorr>.
CALL FUNCTION 'TR_READ_REQUEST_WITH_TASKS'
EXPORTING
iv_trkorr = <ls_trkorr>-trkorr
IMPORTING
et_requests = lt_requests
EXCEPTIONS
invalid_input = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from TR_READ_REQUEST_WITH_TASKS' ).
ENDIF.
APPEND LINES OF lt_requests TO rt_requests.
ENDLOOP.
ENDMETHOD.
METHOD resolve.
DATA: lv_object TYPE tadir-object,
lv_obj_name TYPE tadir-obj_name,
lv_trobj_name TYPE trobj_name,
ls_tadir TYPE zif_abapgit_definitions=>ty_tadir.
FIELD-SYMBOLS: <ls_request> LIKE LINE OF it_requests,
<ls_object> LIKE LINE OF <ls_request>-objects.
LOOP AT it_requests ASSIGNING <ls_request>.
LOOP AT <ls_request>-objects ASSIGNING <ls_object>.
IF <ls_object>-pgmid = 'LIMU'.
CALL FUNCTION 'GET_R3TR_OBJECT_FROM_LIMU_OBJ'
EXPORTING
p_limu_objtype = <ls_object>-object
p_limu_objname = <ls_object>-obj_name
IMPORTING
p_r3tr_objtype = lv_object
p_r3tr_objname = lv_trobj_name
EXCEPTIONS
no_mapping = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from GET_R3TR_OBJECT_FROM_LIMU_OBJ' ).
ENDIF.
lv_obj_name = lv_trobj_name.
ELSE.
lv_object = <ls_object>-object.
lv_obj_name = <ls_object>-obj_name.
ENDIF.
ls_tadir = zcl_abapgit_factory=>get_tadir( )->read_single(
iv_object = lv_object
iv_obj_name = lv_obj_name ).
APPEND ls_tadir TO rt_tadir.
ENDLOOP.
ENDLOOP.
SORT rt_tadir BY object ASCENDING obj_name ASCENDING.
DELETE ADJACENT DUPLICATES FROM rt_tadir COMPARING object obj_name.
DELETE rt_tadir WHERE table_line IS INITIAL.
ENDMETHOD.
METHOD to_tadir.
DATA: lt_requests TYPE trwbo_requests.
IF lines( it_transport_headers ) = 0.
RETURN.
ENDIF.
lt_requests = read_requests( it_transport_headers ).
rt_tadir = resolve( lt_requests ).
ENDMETHOD.
METHOD zip.
DATA: lt_requests TYPE trwbo_requests,
lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt,
lv_package TYPE devclass,
ls_data TYPE zif_abapgit_persistence=>ty_repo,
lo_repo TYPE REF TO zcl_abapgit_repo_offline,
lt_trkorr TYPE trwbo_request_headers.
lt_trkorr = zcl_abapgit_ui_factory=>get_popups( )->popup_to_select_transports( ).
IF lines( lt_trkorr ) = 0.
RETURN.
ENDIF.
lt_requests = read_requests( lt_trkorr ).
lt_tadir = resolve( lt_requests ).
IF lines( lt_tadir ) = 0.
zcx_abapgit_exception=>raise( 'empty transport' ).
ENDIF.
lv_package = find_top_package( lt_tadir ).
IF lv_package IS INITIAL.
zcx_abapgit_exception=>raise( 'error finding super package' ).
ENDIF.
ls_data-key = 'TZIP'.
ls_data-package = lv_package.
ls_data-dot_abapgit = zcl_abapgit_dot_abapgit=>build_default( )->get_data( ).
ls_data-dot_abapgit-folder_logic = zcl_abapgit_ui_factory=>get_popups( )->popup_folder_logic( ).
CREATE OBJECT lo_repo
EXPORTING
is_data = ls_data.
zcl_abapgit_zip=>export( io_repo = lo_repo
it_filter = lt_tadir ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_TADIR IMPLEMENTATION.
METHOD build.
DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt,
lt_tdevc TYPE STANDARD TABLE OF tdevc,
lv_path TYPE string,
lo_skip_objects TYPE REF TO zcl_abapgit_skip_objects,
lt_excludes TYPE RANGE OF trobjtype,
lt_srcsystem TYPE RANGE OF tadir-srcsystem,
ls_srcsystem LIKE LINE OF lt_srcsystem,
ls_exclude LIKE LINE OF lt_excludes.
DATA: lo_folder_logic TYPE REF TO zcl_abapgit_folder_logic.
DATA: last_package TYPE devclass VALUE cl_abap_char_utilities=>horizontal_tab.
FIELD-SYMBOLS: <ls_tdevc> LIKE LINE OF lt_tdevc,
<ls_tadir> LIKE LINE OF rt_tadir,
<lv_package> TYPE devclass.
"Determine Packages to Read
DATA: lt_packages TYPE zif_abapgit_sap_package=>ty_devclass_tt.
IF iv_ignore_subpackages = abap_false.
lt_packages = zcl_abapgit_factory=>get_sap_package( iv_package )->list_subpackages( ).
ENDIF.
INSERT iv_package INTO lt_packages INDEX 1.
ls_exclude-sign = 'I'.
ls_exclude-option = 'EQ'.
ls_exclude-low = 'SOTR'.
APPEND ls_exclude TO lt_excludes.
ls_exclude-low = 'SFB1'.
APPEND ls_exclude TO lt_excludes.
ls_exclude-low = 'SFB2'.
APPEND ls_exclude TO lt_excludes.
ls_exclude-low = 'STOB'. " auto generated by core data services
APPEND ls_exclude TO lt_excludes.
IF iv_only_local_objects = abap_true.
ls_srcsystem-sign = 'I'.
ls_srcsystem-option = 'EQ'.
ls_srcsystem-low = sy-sysid.
APPEND ls_srcsystem TO lt_srcsystem.
ENDIF.
IF lt_packages IS NOT INITIAL.
SELECT * FROM tadir
INTO CORRESPONDING FIELDS OF TABLE rt_tadir
FOR ALL ENTRIES IN lt_packages
WHERE devclass = lt_packages-table_line
AND pgmid = 'R3TR'
AND object NOT IN lt_excludes
AND delflag = abap_false
AND srcsystem IN lt_srcsystem
ORDER BY PRIMARY KEY. "#EC CI_GENBUFF "#EC CI_SUBRC
ENDIF.
SORT rt_tadir BY devclass pgmid object obj_name.
CREATE OBJECT lo_skip_objects.
rt_tadir = lo_skip_objects->skip_sadl_generated_objects(
it_tadir = rt_tadir
io_log = io_log ).
LOOP AT lt_packages ASSIGNING <lv_package>.
" Local packages are not in TADIR, only in TDEVC, act as if they were
IF <lv_package> CP '$*'. " OR <package> CP 'T*' ).
APPEND INITIAL LINE TO rt_tadir ASSIGNING <ls_tadir>.
<ls_tadir>-pgmid = 'R3TR'.
<ls_tadir>-object = 'DEVC'.
<ls_tadir>-obj_name = <lv_package>.
<ls_tadir>-devclass = <lv_package>.
ENDIF.
ENDLOOP.
LOOP AT rt_tadir ASSIGNING <ls_tadir>.
IF last_package <> <ls_tadir>-devclass.
"Change in Package
last_package = <ls_tadir>-devclass.
IF NOT io_dot IS INITIAL.
"Reuse given Folder Logic Instance
IF lo_folder_logic IS NOT BOUND.
"Get Folder Logic Instance
lo_folder_logic = zcl_abapgit_folder_logic=>get_instance( ).
ENDIF.
lv_path = lo_folder_logic->package_to_path(
iv_top = iv_top
io_dot = io_dot
iv_package = <ls_tadir>-devclass ).
ENDIF.
ENDIF.
<ls_tadir>-path = lv_path.
CASE <ls_tadir>-object.
WHEN 'SICF'.
<ls_tadir>-obj_name+15 = zcl_abapgit_object_sicf=>read_sicf_url( <ls_tadir>-obj_name ).
ENDCASE.
ENDLOOP.
ENDMETHOD. "build
METHOD check_exists.
DATA: lv_exists TYPE abap_bool,
lo_progress TYPE REF TO zcl_abapgit_progress,
ls_item TYPE zif_abapgit_definitions=>ty_item.
FIELD-SYMBOLS: <ls_tadir> LIKE LINE OF it_tadir.
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( it_tadir ).
LOOP AT it_tadir ASSIGNING <ls_tadir>.
IF sy-tabix MOD 200 = 0.
lo_progress->show(
iv_current = sy-tabix
iv_text = |Check object exists { <ls_tadir>-object } { <ls_tadir>-obj_name }| ).
ENDIF.
ls_item-obj_type = <ls_tadir>-object.
ls_item-obj_name = <ls_tadir>-obj_name.
ls_item-devclass = <ls_tadir>-devclass.
IF exists( ls_item ) = abap_true.
APPEND <ls_tadir> TO rt_tadir.
ENDIF.
ENDLOOP.
ENDMETHOD. "check_exists
METHOD exists.
IF is_item IS INITIAL.
RETURN.
ENDIF.
IF zcl_abapgit_objects=>is_supported( is_item ) = abap_false.
rv_exists = abap_true.
RETURN.
ENDIF.
rv_exists = zcl_abapgit_objects=>exists( is_item ).
ENDMETHOD.
METHOD zif_abapgit_tadir~get_object_package.
DATA: ls_tadir TYPE zif_abapgit_definitions=>ty_tadir,
ls_item TYPE zif_abapgit_definitions=>ty_item.
ls_tadir = zif_abapgit_tadir~read_single(
iv_pgmid = iv_pgmid
iv_object = iv_object
iv_obj_name = iv_obj_name ).
IF ls_tadir-delflag = 'X'.
RETURN. "Mark for deletion -> return nothing
ENDIF.
ls_item-obj_type = ls_tadir-object.
ls_item-obj_name = ls_tadir-obj_name.
ls_item-devclass = ls_tadir-devclass.
IF exists( ls_item ) = abap_false.
RETURN.
ENDIF.
rv_devclass = ls_tadir-devclass.
ENDMETHOD.
METHOD zif_abapgit_tadir~read.
DATA: li_exit TYPE REF TO zif_abapgit_exit.
rt_tadir = build( iv_package = iv_package
iv_top = iv_package
io_dot = io_dot
iv_ignore_subpackages = iv_ignore_subpackages
iv_only_local_objects = iv_only_local_objects
io_log = io_log ).
li_exit = zcl_abapgit_exit=>get_instance( ).
li_exit->change_tadir(
EXPORTING
iv_package = iv_package
io_log = io_log
CHANGING
ct_tadir = rt_tadir ).
rt_tadir = check_exists( rt_tadir ).
ENDMETHOD.
METHOD zif_abapgit_tadir~read_single.
IF iv_object = 'SICF'.
rs_tadir = zcl_abapgit_object_sicf=>read_tadir_sicf(
iv_pgmid = iv_pgmid
iv_obj_name = iv_obj_name ).
ELSE.
SELECT SINGLE * FROM tadir INTO CORRESPONDING FIELDS OF rs_tadir
WHERE pgmid = iv_pgmid
AND object = iv_object
AND obj_name = iv_obj_name. "#EC CI_SUBRC
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_SYNTAX_CHECK IMPLEMENTATION.
METHOD create_variant.
DATA: lt_variant TYPE sci_tstvar,
ls_variant LIKE LINE OF lt_variant.
cl_ci_checkvariant=>create(
EXPORTING
p_user = sy-uname
RECEIVING
p_ref = ro_variant
EXCEPTIONS
chkv_already_exists = 1
locked = 2
error_in_enqueue = 3
not_authorized = 4
OTHERS = 5 ).
ASSERT sy-subrc = 0.
ls_variant-testname = 'CL_CI_TEST_SYNTAX_CHECK'.
INSERT ls_variant INTO TABLE lt_variant.
ro_variant->set_variant(
EXPORTING
p_variant = lt_variant
EXCEPTIONS
not_enqueued = 1
OTHERS = 2 ).
ASSERT sy-subrc = 0.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_STAGE_LOGIC IMPLEMENTATION.
METHOD get.
rs_files-local = io_repo->get_files_local( ).
rs_files-remote = io_repo->get_files_remote( ).
remove_identical( CHANGING cs_files = rs_files ).
remove_ignored( EXPORTING io_repo = io_repo
CHANGING cs_files = rs_files ).
ENDMETHOD.
METHOD remove_identical.
DATA: lv_index TYPE i,
ls_remote LIKE LINE OF cs_files-remote.
FIELD-SYMBOLS: <ls_local> LIKE LINE OF cs_files-local.
SORT cs_files-remote BY path filename.
LOOP AT cs_files-local ASSIGNING <ls_local>.
lv_index = sy-tabix.
READ TABLE cs_files-remote INTO ls_remote
WITH KEY path = <ls_local>-file-path filename = <ls_local>-file-filename
BINARY SEARCH.
IF sy-subrc = 0.
DELETE cs_files-remote INDEX sy-tabix.
IF ls_remote-sha1 = <ls_local>-file-sha1.
DELETE cs_files-local INDEX lv_index.
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD remove_ignored.
DATA: lv_index TYPE i.
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF cs_files-remote.
LOOP AT cs_files-remote ASSIGNING <ls_remote>.
lv_index = sy-tabix.
IF io_repo->get_dot_abapgit( )->is_ignored(
iv_path = <ls_remote>-path
iv_filename = <ls_remote>-filename ) = abap_true.
DELETE cs_files-remote INDEX lv_index.
ELSEIF <ls_remote>-path = zif_abapgit_definitions=>c_root_dir
AND <ls_remote>-filename = zif_abapgit_definitions=>c_dot_abapgit.
" Remove .abapgit from remotes - it cannot be removed or ignored
DELETE cs_files-remote INDEX lv_index.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_STAGE IMPLEMENTATION.
METHOD add.
append( iv_path = iv_path
iv_filename = iv_filename
iv_method = c_method-add
iv_data = iv_data ).
ENDMETHOD. "add
METHOD append.
DATA: ls_stage LIKE LINE OF mt_stage.
FIELD-SYMBOLS: <ls_stage> LIKE LINE OF mt_stage.
READ TABLE mt_stage WITH KEY
file-path = iv_path
file-filename = iv_filename
ASSIGNING <ls_stage>.
IF sy-subrc = 0.
<ls_stage>-file-data = iv_data.
<ls_stage>-method = iv_method.
ELSE.
ls_stage-file-path = iv_path.
ls_stage-file-filename = iv_filename.
ls_stage-file-data = iv_data.
ls_stage-method = iv_method.
INSERT ls_stage INTO TABLE mt_stage.
ENDIF.
ENDMETHOD. "append
METHOD constructor.
mv_merge_source = iv_merge_source.
ENDMETHOD.
METHOD count.
rv_count = lines( mt_stage ).
ENDMETHOD. "count
METHOD get_all.
rt_stage = mt_stage.
ENDMETHOD. "get_all
METHOD get_merge_source.
rv_source = mv_merge_source.
ENDMETHOD.
METHOD ignore.
append( iv_path = iv_path
iv_filename = iv_filename
iv_method = c_method-ignore ).
ENDMETHOD. "ignore
METHOD method_description.
CASE iv_method.
WHEN c_method-add.
rv_description = 'add'.
WHEN c_method-rm.
rv_description = 'rm'.
WHEN c_method-ignore.
rv_description = 'ignore' ##NO_TEXT.
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'unknown staging method type' ).
ENDCASE.
ENDMETHOD. "method_description
METHOD reset.
DELETE mt_stage WHERE file-path = iv_path
AND file-filename = iv_filename.
ASSERT sy-subrc = 0.
ENDMETHOD. "reset
METHOD rm.
append( iv_path = iv_path
iv_filename = iv_filename
iv_method = c_method-rm ).
ENDMETHOD. "rm
ENDCLASS.
CLASS ZCL_ABAPGIT_SKIP_OBJECTS IMPLEMENTATION.
METHOD has_sadl_superclass.
DATA: li_oo_functions TYPE REF TO zif_abapgit_oo_object_fnc,
lv_class_name TYPE seoclsname,
lv_superclass TYPE seoclsname.
li_oo_functions = zcl_abapgit_oo_factory=>make( is_class-object ).
lv_class_name = is_class-obj_name.
lv_superclass = li_oo_functions->read_superclass( lv_class_name ).
IF lv_superclass = 'CL_SADL_GTK_EXPOSURE_MPC'.
rv_return = abap_true.
ENDIF.
ENDMETHOD.
METHOD skip_sadl_generated_objects.
DATA: ls_tadir_class LIKE LINE OF rt_tadir,
ls_tadir LIKE LINE OF rt_tadir,
lt_lines_to_delete TYPE zif_abapgit_definitions=>ty_tadir_tt.
rt_tadir = it_tadir.
LOOP AT it_tadir INTO ls_tadir WHERE object = 'DDLS'.
LOOP AT rt_tadir INTO ls_tadir_class
WHERE object = 'CLAS' AND obj_name CS ls_tadir-obj_name.
IF has_sadl_superclass( ls_tadir_class ) = abap_true.
APPEND ls_tadir_class TO lt_lines_to_delete.
ENDIF.
ENDLOOP.
ENDLOOP.
DELETE ADJACENT DUPLICATES FROM lt_lines_to_delete.
LOOP AT lt_lines_to_delete INTO ls_tadir_class.
DELETE TABLE rt_tadir FROM ls_tadir_class.
IF io_log IS BOUND.
io_log->add(
iv_msg = |{ ls_tadir_class-obj_name } skipped: generated by SADL|
iv_type = 'W' ).
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_settings IMPLEMENTATION.
METHOD get_adt_jump_enabled.
rv_adt_jump_enabled = ms_user_settings-adt_jump_enabled.
ENDMETHOD.
METHOD get_commitmsg_body_size.
rv_length = ms_settings-commitmsg_body_size.
ENDMETHOD.
METHOD get_commitmsg_comment_length.
rv_length = ms_settings-commitmsg_comment_length.
ENDMETHOD.
METHOD get_experimental_features.
rv_run = ms_settings-experimental_features.
ENDMETHOD.
METHOD get_link_hints_enabled.
rv_link_hints_enabled = ms_user_settings-link_hints_enabled.
ENDMETHOD.
METHOD get_link_hint_key.
rv_link_hint_key = ms_user_settings-link_hint_key.
ENDMETHOD.
METHOD get_max_lines.
rv_lines = ms_user_settings-max_lines.
ENDMETHOD.
METHOD get_proxy_authentication.
rv_auth = ms_settings-proxy_auth.
ENDMETHOD.
METHOD get_proxy_port.
rv_port = ms_settings-proxy_port.
ENDMETHOD.
METHOD get_proxy_url.
rv_proxy_url = ms_settings-proxy_url.
ENDMETHOD.
METHOD get_run_critical_tests.
rv_run = ms_settings-run_critical_tests.
ENDMETHOD.
METHOD get_settings_xml.
DATA: lo_output TYPE REF TO zcl_abapgit_xml_output.
CREATE OBJECT lo_output.
lo_output->add( iv_name = zcl_abapgit_persistence_db=>c_type_settings
ig_data = ms_settings ).
rv_settings_xml = lo_output->render( ).
ENDMETHOD.
METHOD get_show_default_repo.
rv_show_default_repo = ms_user_settings-show_default_repo.
ENDMETHOD.
METHOD get_user_settings.
rs_settings = ms_user_settings.
ENDMETHOD.
METHOD set_adt_jump_enanbled.
ms_user_settings-adt_jump_enabled = iv_adt_jump_enabled.
ENDMETHOD.
METHOD set_commitmsg_body_size.
ms_settings-commitmsg_body_size = iv_length.
ENDMETHOD.
METHOD set_commitmsg_comment_length.
ms_settings-commitmsg_comment_length = iv_length.
ENDMETHOD.
METHOD set_defaults.
CLEAR ms_settings.
set_proxy_authentication( abap_false ).
set_run_critical_tests( abap_false ).
set_experimental_features( abap_false ).
set_max_lines( 500 ).
set_adt_jump_enanbled( abap_true ).
set_show_default_repo( abap_false ).
set_commitmsg_comment_length( c_commitmsg_comment_length_dft ).
set_commitmsg_body_size( c_commitmsg_body_size_dft ).
set_default_link_hint_key( ).
set_default_link_hint_bg_color( ).
ENDMETHOD.
METHOD set_default_link_hint_bg_color.
set_link_hint_background_color( |lightgreen| ).
ENDMETHOD.
METHOD set_default_link_hint_key.
set_link_hint_key( |f| ).
ENDMETHOD.
METHOD set_experimental_features.
ms_settings-experimental_features = iv_run.
ENDMETHOD.
METHOD set_link_hints_enabled.
ms_user_settings-link_hints_enabled = iv_link_hints_enabled.
ENDMETHOD.
METHOD set_link_hint_key.
ms_user_settings-link_hint_key = iv_link_hint_key.
ENDMETHOD.
METHOD set_max_lines.
ms_user_settings-max_lines = iv_lines.
ENDMETHOD.
METHOD set_proxy_authentication.
ms_settings-proxy_auth = iv_auth.
ENDMETHOD.
METHOD set_proxy_port.
ms_settings-proxy_port = iv_port.
ENDMETHOD.
METHOD set_proxy_url.
ms_settings-proxy_url = iv_url.
ENDMETHOD.
METHOD set_run_critical_tests.
ms_settings-run_critical_tests = iv_run.
ENDMETHOD.
METHOD set_show_default_repo.
ms_user_settings-show_default_repo = iv_show_default_repo.
ENDMETHOD.
METHOD set_user_settings.
ms_user_settings = is_user_settings.
IF ms_user_settings-link_hint_key IS INITIAL.
set_default_link_hint_key( ).
ENDIF.
IF ms_user_settings-link_hint_background_color IS INITIAL.
set_default_link_hint_bg_color( ).
ENDIF.
ENDMETHOD.
METHOD set_xml_settings.
DATA: lo_input TYPE REF TO zcl_abapgit_xml_input.
CREATE OBJECT lo_input EXPORTING iv_xml = iv_settings_xml.
CLEAR ms_settings.
lo_input->read(
EXPORTING
iv_name = zcl_abapgit_persistence_db=>c_type_settings
CHANGING
cg_data = ms_settings ).
ENDMETHOD.
METHOD get_link_hint_background_color.
rv_background_color = ms_user_settings-link_hint_background_color.
ENDMETHOD.
METHOD set_link_hint_background_color.
ms_user_settings-link_hint_background_color = iv_background_color.
ENDMETHOD.
METHOD set_hotkeys.
ms_user_settings-hotkeys = it_hotkeys.
ENDMETHOD.
METHOD get_hotkeys.
DATA: lt_default_hotkeys TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action,
ls_hotkey LIKE LINE OF rt_hotkeys.
FIELD-SYMBOLS: <ls_default_hotkey> LIKE LINE OF lt_default_hotkeys.
IF lines( ms_user_settings-hotkeys ) > 0.
rt_hotkeys = ms_user_settings-hotkeys.
ELSE.
" provide default hotkeys
lt_default_hotkeys = zcl_abapgit_hotkeys=>get_default_hotkeys_from_pages( ).
LOOP AT lt_default_hotkeys ASSIGNING <ls_default_hotkey>.
ls_hotkey-action = <ls_default_hotkey>-action.
ls_hotkey-sequence = <ls_default_hotkey>-default_hotkey.
INSERT ls_hotkey INTO TABLE rt_hotkeys.
ENDLOOP.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_SAP_PACKAGE IMPLEMENTATION.
METHOD constructor.
mv_package = iv_package.
ENDMETHOD.
METHOD zif_abapgit_sap_package~are_changes_recorded_in_tr_req.
DATA: li_package TYPE REF TO if_package.
cl_package_factory=>load_package(
EXPORTING
i_package_name = mv_package
IMPORTING
e_package = li_package
EXCEPTIONS
object_not_existing = 1
unexpected_error = 2
intern_err = 3
no_access = 4
object_locked_and_modified = 5
OTHERS = 6 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from CL_PACKAGE_FACTORY=>LOAD_PACKAGE { sy-subrc }| ).
ENDIF.
rv_are_changes_rec_in_tr_req = li_package->wbo_korr_flag.
ENDMETHOD.
METHOD zif_abapgit_sap_package~create.
DATA: lv_err TYPE string,
li_package TYPE REF TO if_package,
ls_package LIKE is_package.
ASSERT NOT is_package-devclass IS INITIAL.
cl_package_factory=>load_package(
EXPORTING
i_package_name = is_package-devclass
EXCEPTIONS
object_not_existing = 1
unexpected_error = 2
intern_err = 3
no_access = 4
object_locked_and_modified = 5 ).
IF sy-subrc = 0.
" Package already exists. We assume this is fine. Its properties might be changed later at
" DEVC deserialization.
RETURN.
ENDIF.
ls_package = is_package.
" Set software component to 'HOME' if none is set at this point.
" Otherwise SOFTWARE_COMPONENT_INVALID will be raised.
IF ls_package-dlvunit IS INITIAL.
ls_package-dlvunit = 'HOME'.
ENDIF.
cl_package_factory=>create_new_package(
EXPORTING
i_reuse_deleted_object = abap_true
IMPORTING
e_package = li_package
CHANGING
c_package_data = ls_package
EXCEPTIONS
object_already_existing = 1
object_just_created = 2
not_authorized = 3
wrong_name_prefix = 4
undefined_name = 5
reserved_local_name = 6
invalid_package_name = 7
short_text_missing = 8
software_component_invalid = 9
layer_invalid = 10
author_not_existing = 11
component_not_existing = 12
component_missing = 13
prefix_in_use = 14
unexpected_error = 15
intern_err = 16
no_access = 17
OTHERS = 18 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Package { is_package-devclass } could not be created| ).
ENDIF.
li_package->save(
EXCEPTIONS
object_invalid = 1
object_not_changeable = 2
cancelled_in_corr = 3
permission_failure = 4
unexpected_error = 5
intern_err = 6
OTHERS = 7 ).
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 INTO lv_err.
" Here we have to delete the package,
" otherwise it would remain in the memory
" and cannot created again in this session.
li_package->delete(
EXCEPTIONS
object_not_empty = 1
object_not_changeable = 2
object_invalid = 3
intern_err = 4
OTHERS = 5 ).
zcx_abapgit_exception=>raise( lv_err ).
ENDIF.
li_package->set_changeable( abap_false ).
ENDMETHOD.
METHOD zif_abapgit_sap_package~create_child.
DATA: li_parent TYPE REF TO if_package,
ls_child TYPE scompkdtln.
cl_package_factory=>load_package(
EXPORTING
i_package_name = mv_package
IMPORTING
e_package = li_parent
EXCEPTIONS
object_not_existing = 1
unexpected_error = 2
intern_err = 3
no_access = 4
object_locked_and_modified = 5 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error reading parent package' ).
ENDIF.
ls_child-devclass = iv_child.
ls_child-dlvunit = li_parent->software_component.
ls_child-component = li_parent->application_component.
ls_child-ctext = iv_child.
ls_child-parentcl = mv_package.
ls_child-pdevclass = li_parent->transport_layer.
ls_child-as4user = sy-uname.
create( ls_child ).
ENDMETHOD.
METHOD zif_abapgit_sap_package~create_local.
DATA: ls_package TYPE scompkdtln.
ls_package-devclass = mv_package.
ls_package-ctext = mv_package.
ls_package-parentcl = '$TMP'.
ls_package-dlvunit = 'LOCAL'.
ls_package-as4user = sy-uname.
create( ls_package ).
ENDMETHOD. "create
METHOD zif_abapgit_sap_package~exists.
cl_package_factory=>load_package(
EXPORTING
i_package_name = mv_package
EXCEPTIONS
object_not_existing = 1
unexpected_error = 2
intern_err = 3
no_access = 4
object_locked_and_modified = 5 ).
rv_bool = boolc( sy-subrc <> 1 ).
ENDMETHOD.
METHOD zif_abapgit_sap_package~get_transport_type.
DATA: lv_err_prefix TYPE string,
lv_pkg_name TYPE e071-obj_name.
lv_err_prefix = |TRINT_GET_REQUEST_TYPE(R3TR, DEVC, { mv_package })|.
lv_pkg_name = mv_package.
CALL FUNCTION 'TRINT_GET_REQUEST_TYPE'
EXPORTING
iv_pgmid = 'R3TR'
iv_object = 'DEVC'
iv_obj_name = lv_pkg_name
IMPORTING
ev_request_type = rv_transport_type-request
ev_task_type = rv_transport_type-task
EXCEPTIONS
no_request_needed = 1
internal_error = 2
cts_initialization_failure = 3.
CASE sy-subrc.
WHEN 0.
" OK!
WHEN 1.
zcx_abapgit_exception=>raise( |{ lv_err_prefix }: transport is not needed| ).
WHEN 2.
zcx_abapgit_exception=>raise( |{ lv_err_prefix }: internal error| ).
WHEN 3.
zcx_abapgit_exception=>raise( |{ lv_err_prefix }: failed to initialized CTS| ).
WHEN OTHERS.
zcx_abapgit_exception=>raise( |{ lv_err_prefix }: unrecognized return code| ).
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_sap_package~list_subpackages.
DATA: lt_list LIKE rt_list.
SELECT devclass FROM tdevc
INTO TABLE lt_list
WHERE parentcl = mv_package
ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF
rt_list = lt_list.
WHILE lines( lt_list ) > 0.
SELECT devclass FROM tdevc
INTO TABLE lt_list
FOR ALL ENTRIES IN lt_list
WHERE parentcl = lt_list-table_line
ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF
APPEND LINES OF lt_list TO rt_list.
ENDWHILE.
ENDMETHOD.
METHOD zif_abapgit_sap_package~list_superpackages.
DATA: lt_list LIKE rt_list,
lv_parent TYPE tdevc-parentcl.
APPEND mv_package TO rt_list.
lv_parent = zif_abapgit_sap_package~read_parent( ).
IF sy-subrc = 0 AND NOT lv_parent IS INITIAL.
lt_list = zcl_abapgit_factory=>get_sap_package( lv_parent )->list_superpackages( ).
APPEND LINES OF lt_list TO rt_list.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_sap_package~read_parent.
SELECT SINGLE parentcl FROM tdevc INTO rv_parentcl
WHERE devclass = mv_package. "#EC CI_SUBRC "#EC CI_GENBUFF
ASSERT sy-subrc = 0.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_REPO_SRV IMPLEMENTATION.
METHOD add.
DATA: lo_repo LIKE LINE OF mt_list.
LOOP AT mt_list INTO lo_repo.
IF lo_repo->get_key( ) = io_repo->get_key( ).
IF lo_repo = io_repo.
RETURN.
ENDIF.
zcx_abapgit_exception=>raise( 'identical keys' ).
ENDIF.
ENDLOOP.
APPEND io_repo TO mt_list.
ENDMETHOD. "add
METHOD constructor.
ENDMETHOD.
METHOD get_instance.
IF gi_ref IS INITIAL.
CREATE OBJECT gi_ref TYPE zcl_abapgit_repo_srv.
ENDIF.
ri_srv = gi_ref.
ENDMETHOD.
METHOD is_sap_object_allowed.
rv_allowed = cl_enh_badi_def_utility=>is_sap_system( ).
IF rv_allowed = abap_true.
RETURN.
ENDIF.
rv_allowed = zcl_abapgit_exit=>get_instance( )->allow_sap_objects( ).
ENDMETHOD.
METHOD refresh.
DATA: lt_list TYPE zif_abapgit_persistence=>tt_repo,
lo_online TYPE REF TO zcl_abapgit_repo_online,
lo_offline TYPE REF TO zcl_abapgit_repo_offline.
FIELD-SYMBOLS: <ls_list> LIKE LINE OF lt_list.
CLEAR mt_list.
lt_list = zcl_abapgit_persist_factory=>get_repo( )->list( ).
LOOP AT lt_list ASSIGNING <ls_list>.
IF <ls_list>-offline = abap_false.
CREATE OBJECT lo_online
EXPORTING
is_data = <ls_list>.
APPEND lo_online TO mt_list.
ELSE.
CREATE OBJECT lo_offline
EXPORTING
is_data = <ls_list>.
APPEND lo_offline TO mt_list.
ENDIF.
ENDLOOP.
mv_init = abap_true.
ENDMETHOD. "refresh
METHOD validate_sub_super_packages.
DATA:
ls_repo LIKE LINE OF it_repos,
lo_package TYPE REF TO zif_abapgit_sap_package,
lt_packages TYPE zif_abapgit_sap_package=>ty_devclass_tt,
lo_repo TYPE REF TO zcl_abapgit_repo.
LOOP AT it_repos INTO ls_repo.
lo_repo = get( ls_repo-key ).
lo_package = zcl_abapgit_factory=>get_sap_package( ls_repo-package ).
IF lo_package->exists( ) eq ABAP_FALSE.
" Skip dangling repository
CONTINUE.
ENDIF.
CLEAR lt_packages.
IF lo_repo->get_local_settings( )-ignore_subpackages = abap_false.
APPEND LINES OF lo_package->list_subpackages( ) TO lt_packages.
ENDIF.
APPEND LINES OF lo_package->list_superpackages( ) TO lt_packages.
READ TABLE lt_packages TRANSPORTING NO FIELDS
WITH KEY table_line = iv_package.
IF sy-subrc = 0.
zcx_abapgit_exception=>raise( |Repository { lo_repo->get_name( ) } already contains { iv_package } | ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_repo_srv~delete.
io_repo->delete( ).
DELETE TABLE mt_list FROM io_repo.
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD zif_abapgit_repo_srv~get.
FIELD-SYMBOLS: <lo_list> LIKE LINE OF mt_list.
IF mv_init = abap_false.
refresh( ).
ENDIF.
LOOP AT mt_list ASSIGNING <lo_list>.
IF <lo_list>->get_key( ) = iv_key.
ro_repo = <lo_list>.
RETURN.
ENDIF.
ENDLOOP.
zcx_abapgit_exception=>raise( 'repo not found, get' ).
ENDMETHOD.
METHOD zif_abapgit_repo_srv~is_repo_installed.
DATA: lt_repo TYPE zif_abapgit_definitions=>ty_repo_ref_tt,
lo_repo TYPE REF TO zcl_abapgit_repo,
lv_url TYPE string,
lv_package TYPE devclass,
lo_repo_online TYPE REF TO zcl_abapgit_repo_online,
lv_err TYPE string.
lt_repo = list( ).
LOOP AT lt_repo INTO lo_repo.
CHECK lo_repo->is_offline( ) = abap_false.
lo_repo_online ?= lo_repo.
lv_url = lo_repo_online->get_url( ).
lv_package = lo_repo_online->get_package( ).
CHECK to_upper( lv_url ) = to_upper( iv_url ).
" Validate bindings
"TODO refactor: move this message out of this method
IF iv_target_package IS NOT INITIAL AND iv_target_package <> lv_package.
lv_err = |Installation to package { lv_package } detected. |
&& |Cancelling installation|.
zcx_abapgit_exception=>raise( lv_err ).
ENDIF.
rv_installed = abap_true.
EXIT.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_repo_srv~list.
IF mv_init = abap_false.
refresh( ).
ENDIF.
rt_list = mt_list.
ENDMETHOD.
METHOD zif_abapgit_repo_srv~new_offline.
DATA: ls_repo TYPE zif_abapgit_persistence=>ty_repo,
lv_key TYPE zif_abapgit_persistence=>ty_repo-key.
validate_package( iv_package ).
lv_key = zcl_abapgit_persist_factory=>get_repo( )->add(
iv_url = iv_url
iv_branch_name = ''
iv_package = iv_package
iv_offline = abap_true
is_dot_abapgit = zcl_abapgit_dot_abapgit=>build_default( )->get_data( ) ).
TRY.
ls_repo = zcl_abapgit_persist_factory=>get_repo( )->read( lv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'new_offline not found' ).
ENDTRY.
CREATE OBJECT ro_repo
EXPORTING
is_data = ls_repo.
add( ro_repo ).
ENDMETHOD.
METHOD zif_abapgit_repo_srv~new_online.
DATA: ls_repo TYPE zif_abapgit_persistence=>ty_repo,
lv_key TYPE zif_abapgit_persistence=>ty_repo-key.
ASSERT NOT iv_url IS INITIAL
AND NOT iv_branch_name IS INITIAL
AND NOT iv_package IS INITIAL.
validate_package( iv_package ).
zcl_abapgit_url=>validate( |{ iv_url }| ).
lv_key = zcl_abapgit_persist_factory=>get_repo( )->add(
iv_url = iv_url
iv_branch_name = iv_branch_name
iv_package = iv_package
iv_offline = abap_false
is_dot_abapgit = zcl_abapgit_dot_abapgit=>build_default( )->get_data( ) ).
TRY.
ls_repo = zcl_abapgit_persist_factory=>get_repo( )->read( lv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'new_online not found' ).
ENDTRY.
CREATE OBJECT ro_repo
EXPORTING
is_data = ls_repo.
add( ro_repo ).
ro_repo->refresh( ).
ro_repo->find_remote_dot_abapgit( ).
ENDMETHOD.
METHOD zif_abapgit_repo_srv~purge.
DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt.
IF io_repo->get_local_settings( )-write_protected = abap_true.
zcx_abapgit_exception=>raise( 'Cannot purge. Local code is write-protected by repo config' ).
ELSEIF zcl_abapgit_auth=>is_allowed( zif_abapgit_auth=>gc_authorization-uninstall ) = abap_false.
zcx_abapgit_exception=>raise( 'Not authorized' ).
ENDIF.
lt_tadir = zcl_abapgit_factory=>get_tadir( )->read( io_repo->get_package( ) ).
zcl_abapgit_objects=>delete( it_tadir = lt_tadir
is_checks = is_checks ).
delete( io_repo ).
ENDMETHOD.
METHOD zif_abapgit_repo_srv~switch_repo_type.
DATA lo_repo TYPE REF TO zcl_abapgit_repo.
FIELD-SYMBOLS <lo_repo> LIKE LINE OF mt_list.
lo_repo = get( iv_key ).
READ TABLE mt_list ASSIGNING <lo_repo> FROM lo_repo.
ASSERT sy-subrc IS INITIAL.
ASSERT iv_offline <> lo_repo->ms_data-offline.
IF iv_offline = abap_true. " On-line -> OFFline
lo_repo->set(
iv_url = zcl_abapgit_url=>name( lo_repo->ms_data-url )
iv_branch_name = ''
iv_head_branch = ''
iv_offline = abap_true ).
CREATE OBJECT <lo_repo> TYPE zcl_abapgit_repo_offline
EXPORTING
is_data = lo_repo->ms_data.
ELSE. " OFFline -> On-line
lo_repo->set( iv_offline = abap_false ).
CREATE OBJECT <lo_repo> TYPE zcl_abapgit_repo_online
EXPORTING
is_data = lo_repo->ms_data.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_repo_srv~validate_package.
DATA: lv_as4user TYPE tdevc-as4user,
lt_repos TYPE zif_abapgit_persistence=>tt_repo.
IF iv_package IS INITIAL.
zcx_abapgit_exception=>raise( 'add, package empty' ).
ENDIF.
IF iv_package = '$TMP'.
zcx_abapgit_exception=>raise( 'not possible to use $TMP, create new (local) package' ).
ENDIF.
SELECT SINGLE as4user FROM tdevc
INTO lv_as4user
WHERE devclass = iv_package. "#EC CI_GENBUFF
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Package { iv_package } not found| ).
ENDIF.
IF is_sap_object_allowed( ) = abap_false AND lv_as4user = 'SAP'.
zcx_abapgit_exception=>raise( |Package { iv_package } not allowed| ).
ENDIF.
" make sure its not already in use for a different repository
lt_repos = zcl_abapgit_persist_factory=>get_repo( )->list( ).
READ TABLE lt_repos WITH KEY package = iv_package TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
zcx_abapgit_exception=>raise( |Package { iv_package } already in use| ).
ENDIF.
validate_sub_super_packages(
iv_package = iv_package
it_repos = lt_repos ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_REPO_ONLINE IMPLEMENTATION.
METHOD constructor.
super->constructor( is_data ).
mv_initialized = abap_false.
ENDMETHOD. "constructor
METHOD deserialize.
initialize( ).
super->deserialize( is_checks ).
reset_status( ).
COMMIT WORK AND WAIT.
ENDMETHOD. "deserialize
METHOD get_branch_name.
rv_name = ms_data-branch_name.
ENDMETHOD. "get_branch_name
METHOD get_files_remote.
initialize( ).
rt_files = mt_remote.
ENDMETHOD. "get_files
METHOD get_objects.
initialize( ).
rt_objects = mt_objects.
ENDMETHOD. "get_objects
METHOD get_sha1_remote.
initialize( ).
rv_sha1 = mv_branch.
ENDMETHOD. "get_sha1_remote
METHOD get_unnecessary_local_objs.
DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt,
lt_tadir_unique TYPE HASHED TABLE OF zif_abapgit_definitions=>ty_tadir
WITH UNIQUE KEY pgmid object obj_name,
lt_local TYPE zif_abapgit_definitions=>ty_files_item_tt,
lt_remote TYPE zif_abapgit_definitions=>ty_files_tt,
lt_status TYPE zif_abapgit_definitions=>ty_results_tt,
lv_package TYPE zif_abapgit_persistence=>ty_repo-package.
FIELD-SYMBOLS: <ls_status> TYPE zif_abapgit_definitions=>ty_result,
<ls_tadir> TYPE zif_abapgit_definitions=>ty_tadir.
" delete objects which are added locally but are not in remote repo
lt_local = get_files_local( ).
lt_remote = get_files_remote( ).
lt_status = status( ).
lv_package = get_package( ).
lt_tadir = zcl_abapgit_factory=>get_tadir( )->read( lv_package ).
SORT lt_tadir BY pgmid ASCENDING object ASCENDING obj_name ASCENDING devclass ASCENDING.
LOOP AT lt_status ASSIGNING <ls_status>
WHERE lstate = zif_abapgit_definitions=>c_state-added.
READ TABLE lt_tadir ASSIGNING <ls_tadir>
WITH KEY pgmid = 'R3TR'
object = <ls_status>-obj_type
obj_name = <ls_status>-obj_name
devclass = <ls_status>-package
BINARY SEARCH.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
INSERT <ls_tadir> INTO TABLE lt_tadir_unique.
ENDLOOP.
rt_unnecessary_local_objects = lt_tadir_unique.
ENDMETHOD.
METHOD get_url.
rv_url = ms_data-url.
ENDMETHOD. "get_url
METHOD handle_stage_ignore.
DATA: lv_add TYPE abap_bool,
lo_dot_abapgit TYPE REF TO zcl_abapgit_dot_abapgit,
lt_stage TYPE zcl_abapgit_stage=>ty_stage_tt.
FIELD-SYMBOLS: <ls_stage> LIKE LINE OF lt_stage.
lo_dot_abapgit = get_dot_abapgit( ).
lt_stage = io_stage->get_all( ).
LOOP AT lt_stage ASSIGNING <ls_stage> WHERE method = zcl_abapgit_stage=>c_method-ignore.
lo_dot_abapgit->add_ignore(
iv_path = <ls_stage>-file-path
iv_filename = <ls_stage>-file-filename ).
" remove it from the staging object, as the action is handled here
io_stage->reset( iv_path = <ls_stage>-file-path
iv_filename = <ls_stage>-file-filename ).
lv_add = abap_true.
ENDLOOP.
IF lv_add = abap_true.
io_stage->add(
iv_path = zif_abapgit_definitions=>c_root_dir
iv_filename = zif_abapgit_definitions=>c_dot_abapgit
iv_data = lo_dot_abapgit->serialize( ) ).
set_dot_abapgit( lo_dot_abapgit ).
ENDIF.
ENDMETHOD.
METHOD initialize.
IF mv_initialized = abap_false.
refresh( ).
ENDIF.
ENDMETHOD.
METHOD rebuild_local_checksums. "REMOTE
DATA: lt_remote TYPE zif_abapgit_definitions=>ty_files_tt,
lt_local TYPE zif_abapgit_definitions=>ty_files_item_tt,
ls_last_item TYPE zif_abapgit_definitions=>ty_item,
lt_checksums TYPE zif_abapgit_persistence=>ty_local_checksum_tt.
FIELD-SYMBOLS: <ls_checksum> LIKE LINE OF lt_checksums,
<ls_file_sig> LIKE LINE OF <ls_checksum>-files,
<ls_remote> LIKE LINE OF lt_remote,
<ls_local> LIKE LINE OF lt_local.
lt_remote = get_files_remote( ).
lt_local = get_files_local( ).
DELETE lt_local " Remove non-code related files except .abapgit
WHERE item IS INITIAL
AND NOT ( file-path = zif_abapgit_definitions=>c_root_dir
AND file-filename = zif_abapgit_definitions=>c_dot_abapgit ).
SORT lt_local BY item.
SORT lt_remote BY path filename.
LOOP AT lt_local ASSIGNING <ls_local>.
IF ls_last_item <> <ls_local>-item OR sy-tabix = 1. " First or New item reached ?
APPEND INITIAL LINE TO lt_checksums ASSIGNING <ls_checksum>.
<ls_checksum>-item = <ls_local>-item.
ls_last_item = <ls_local>-item.
ENDIF.
READ TABLE lt_remote ASSIGNING <ls_remote>
WITH KEY path = <ls_local>-file-path filename = <ls_local>-file-filename
BINARY SEARCH.
CHECK sy-subrc = 0. " Ignore new ones
APPEND INITIAL LINE TO <ls_checksum>-files ASSIGNING <ls_file_sig>.
MOVE-CORRESPONDING <ls_local>-file TO <ls_file_sig>.
" If hashes are equal -> local sha1 is OK
" Else if R-branch is ahead -> assume changes were remote, state - local sha1
" Else (branches equal) -> assume changes were local, state - remote sha1
IF <ls_local>-file-sha1 <> <ls_remote>-sha1.
<ls_file_sig>-sha1 = <ls_remote>-sha1.
ENDIF.
ENDLOOP.
set( it_checksums = lt_checksums ).
reset_status( ).
ENDMETHOD. " rebuild_local_checksums.
METHOD refresh.
DATA: lo_progress TYPE REF TO zcl_abapgit_progress,
ls_pull TYPE zcl_abapgit_git_porcelain=>ty_pull_result,
lx_exception TYPE REF TO zcx_abapgit_exception.
super->refresh( iv_drop_cache ).
reset_status( ).
CREATE OBJECT lo_progress
EXPORTING
iv_total = 1.
lo_progress->show( iv_current = 1
iv_text = 'Fetch remote files' ) ##NO_TEXT.
ls_pull = zcl_abapgit_git_porcelain=>pull(
iv_url = get_url( )
iv_branch_name = get_branch_name( ) ).
mt_remote = ls_pull-files.
mt_objects = ls_pull-objects.
mv_branch = ls_pull-branch.
mv_initialized = abap_true.
ENDMETHOD. "refresh
METHOD reset_status.
CLEAR mt_status.
ENDMETHOD. " reset_status.
METHOD set_branch_name.
IF ms_data-local_settings-write_protected = abap_true.
zcx_abapgit_exception=>raise( 'Cannot switch branch. Local code is write-protected by repo config' ).
ENDIF.
mv_initialized = abap_false.
set( iv_branch_name = iv_branch_name ).
ENDMETHOD.
METHOD set_objects.
mt_objects = it_objects.
ENDMETHOD.
METHOD set_url.
IF ms_data-local_settings-write_protected = abap_true.
zcx_abapgit_exception=>raise( 'Cannot change URL. Local code is write-protected by repo config' ).
ENDIF.
mv_initialized = abap_false.
set( iv_url = iv_url ).
ENDMETHOD.
METHOD status.
initialize( ).
IF lines( mt_status ) = 0.
mt_status = zcl_abapgit_file_status=>status( io_repo = me
io_log = io_log ).
ENDIF.
rt_results = mt_status.
ENDMETHOD. "status
METHOD zif_abapgit_git_operations~create_branch.
DATA: lv_sha1 TYPE zif_abapgit_definitions=>ty_sha1.
ASSERT iv_name CP 'refs/heads/+*'.
IF iv_from IS INITIAL.
lv_sha1 = get_sha1_remote( ).
ELSE.
lv_sha1 = iv_from.
ENDIF.
zcl_abapgit_git_porcelain=>create_branch(
iv_url = get_url( )
iv_name = iv_name
iv_from = lv_sha1 ).
" automatically switch to new branch
set_branch_name( iv_name ).
ENDMETHOD.
METHOD zif_abapgit_git_operations~push.
DATA: ls_push TYPE zcl_abapgit_git_porcelain=>ty_push_result,
lv_text TYPE string.
IF ms_data-branch_name CP 'refs/tags*'.
lv_text = |You're working on a tag. Currently it's not |
&& |possible to push on tags. Consider creating a branch instead|.
zcx_abapgit_exception=>raise( lv_text ).
ENDIF.
IF ms_data-local_settings-block_commit = abap_true
AND mv_code_inspector_successful = abap_false.
zcx_abapgit_exception=>raise( |A successful code inspection is required| ).
ENDIF.
handle_stage_ignore( io_stage ).
ls_push = zcl_abapgit_git_porcelain=>push(
is_comment = is_comment
io_stage = io_stage
iv_branch_name = get_branch_name( )
iv_url = get_url( )
iv_parent = get_sha1_remote( )
it_old_objects = get_objects( ) ).
set_objects( ls_push-new_objects ).
set_files_remote( ls_push-new_files ).
mv_branch = ls_push-branch.
update_local_checksums( ls_push-updated_files ).
reset_status( ).
CLEAR: mv_code_inspector_successful.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_REPO_OFFLINE IMPLEMENTATION.
ENDCLASS.
CLASS zcl_abapgit_repo_content_list IMPLEMENTATION.
METHOD build_folders.
DATA: lv_index TYPE i,
lt_subitems LIKE ct_repo_items,
ls_subitem LIKE LINE OF ct_repo_items,
ls_folder LIKE LINE OF ct_repo_items.
FIELD-SYMBOLS <ls_item> LIKE LINE OF ct_repo_items.
LOOP AT ct_repo_items ASSIGNING <ls_item>.
lv_index = sy-tabix.
CHECK <ls_item>-path <> iv_cur_dir. " files in target dir - just leave them be
IF zcl_abapgit_path=>is_subdir( iv_path = <ls_item>-path iv_parent = iv_cur_dir ) = abap_true.
ls_subitem-changes = <ls_item>-changes.
ls_subitem-path = <ls_item>-path.
ls_subitem-lstate = <ls_item>-lstate.
ls_subitem-rstate = <ls_item>-rstate.
APPEND ls_subitem TO lt_subitems.
ENDIF.
DELETE ct_repo_items INDEX lv_index.
ENDLOOP.
SORT lt_subitems BY path ASCENDING.
LOOP AT lt_subitems ASSIGNING <ls_item>.
AT NEW path.
CLEAR ls_folder.
ls_folder-path = <ls_item>-path.
ls_folder-sortkey = c_sortkey-dir. " Directory
ls_folder-is_dir = abap_true.
ENDAT.
ls_folder-changes = ls_folder-changes + <ls_item>-changes.
zcl_abapgit_state=>reduce( EXPORTING iv_cur = <ls_item>-lstate
CHANGING cv_prev = ls_folder-lstate ).
zcl_abapgit_state=>reduce( EXPORTING iv_cur = <ls_item>-rstate
CHANGING cv_prev = ls_folder-rstate ).
AT END OF path.
APPEND ls_folder TO ct_repo_items.
ENDAT.
ENDLOOP.
ENDMETHOD. "build_folders
METHOD build_repo_items_offline.
DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt.
FIELD-SYMBOLS: <ls_repo_item> LIKE LINE OF rt_repo_items,
<ls_tadir> LIKE LINE OF lt_tadir.
lt_tadir = zcl_abapgit_factory=>get_tadir( )->read(
iv_package = mo_repo->get_package( )
io_dot = mo_repo->get_dot_abapgit( ) ).
LOOP AT lt_tadir ASSIGNING <ls_tadir>.
APPEND INITIAL LINE TO rt_repo_items ASSIGNING <ls_repo_item>.
<ls_repo_item>-obj_type = <ls_tadir>-object.
<ls_repo_item>-obj_name = <ls_tadir>-obj_name.
<ls_repo_item>-path = <ls_tadir>-path.
<ls_repo_item>-sortkey = c_sortkey-default. " Default sort key
ENDLOOP.
ENDMETHOD. "build_repo_items_offline
METHOD build_repo_items_online.
DATA: lo_repo_online TYPE REF TO zcl_abapgit_repo_online,
ls_file TYPE zif_abapgit_definitions=>ty_repo_file,
lt_status TYPE zif_abapgit_definitions=>ty_results_tt.
FIELD-SYMBOLS: <ls_status> LIKE LINE OF lt_status,
<ls_repo_item> LIKE LINE OF rt_repo_items.
lo_repo_online ?= mo_repo.
lt_status = lo_repo_online->status( mo_log ).
LOOP AT lt_status ASSIGNING <ls_status>.
AT NEW obj_name. "obj_type + obj_name
APPEND INITIAL LINE TO rt_repo_items ASSIGNING <ls_repo_item>.
<ls_repo_item>-obj_type = <ls_status>-obj_type.
<ls_repo_item>-obj_name = <ls_status>-obj_name.
<ls_repo_item>-sortkey = c_sortkey-default. " Default sort key
<ls_repo_item>-changes = 0.
<ls_repo_item>-path = <ls_status>-path.
ENDAT.
IF <ls_status>-filename IS NOT INITIAL.
ls_file-path = <ls_status>-path.
ls_file-filename = <ls_status>-filename.
ls_file-is_changed = boolc( <ls_status>-match = abap_false ). " TODO refactor
ls_file-rstate = <ls_status>-rstate.
ls_file-lstate = <ls_status>-lstate.
APPEND ls_file TO <ls_repo_item>-files.
IF ls_file-is_changed = abap_true.
<ls_repo_item>-sortkey = c_sortkey-changed. " Changed files
<ls_repo_item>-changes = <ls_repo_item>-changes + 1.
zcl_abapgit_state=>reduce( EXPORTING iv_cur = ls_file-lstate
CHANGING cv_prev = <ls_repo_item>-lstate ).
zcl_abapgit_state=>reduce( EXPORTING iv_cur = ls_file-rstate
CHANGING cv_prev = <ls_repo_item>-rstate ).
ENDIF.
ENDIF.
AT END OF obj_name. "obj_type + obj_name
IF <ls_repo_item>-obj_type IS INITIAL.
<ls_repo_item>-sortkey = c_sortkey-orphan. "Virtual objects
ENDIF.
ENDAT.
ENDLOOP.
ENDMETHOD. "build_repo_items_online
METHOD constructor.
mo_repo = io_repo.
CREATE OBJECT mo_log.
ENDMETHOD. "constructor
METHOD filter_changes.
DELETE ct_repo_items WHERE changes = 0.
ENDMETHOD. "filter_changes
METHOD get_log.
ro_log = mo_log.
ENDMETHOD. "get_log
METHOD list.
mo_log->clear( ).
IF mo_repo->is_offline( ) = abap_true.
rt_repo_items = build_repo_items_offline( ).
ELSE.
rt_repo_items = build_repo_items_online( ).
ENDIF.
IF iv_by_folders = abap_true.
build_folders(
EXPORTING iv_cur_dir = iv_path
CHANGING ct_repo_items = rt_repo_items ).
ENDIF.
IF iv_changes_only = abap_true AND mo_repo->is_offline( ) = abap_false.
" There are never changes for offline repositories
filter_changes( CHANGING ct_repo_items = rt_repo_items ).
ENDIF.
SORT rt_repo_items BY
sortkey ASCENDING
obj_type ASCENDING
obj_name ASCENDING.
ENDMETHOD. "list
ENDCLASS.
CLASS ZCL_ABAPGIT_REPO IMPLEMENTATION.
METHOD constructor.
ASSERT NOT is_data-key IS INITIAL.
ms_data = is_data.
ENDMETHOD. "constructor
METHOD delete.
zcl_abapgit_persist_factory=>get_repo( )->delete( ms_data-key ).
ENDMETHOD.
METHOD delete_checks.
DATA: li_package TYPE REF TO zif_abapgit_sap_package.
li_package = zcl_abapgit_factory=>get_sap_package( get_package( ) ).
rs_checks-transport-required = li_package->are_changes_recorded_in_tr_req( ).
ENDMETHOD.
METHOD deserialize.
DATA: lt_updated_files TYPE zif_abapgit_definitions=>ty_file_signatures_tt,
lx_error TYPE REF TO zcx_abapgit_exception.
deserialize_checks( ).
IF is_checks-requirements-met = 'N' AND is_checks-requirements-decision IS INITIAL.
zcx_abapgit_exception=>raise( 'Requirements not met and undecided ').
ENDIF.
IF is_checks-transport-required = abap_true AND is_checks-transport-transport IS INITIAL.
zcx_abapgit_exception=>raise( |No transport request was supplied| ).
ENDIF.
TRY.
lt_updated_files = zcl_abapgit_objects=>deserialize(
io_repo = me
is_checks = is_checks ).
CATCH zcx_abapgit_exception INTO lx_error.
zcl_abapgit_default_transport=>get_instance( )->reset( ).
RAISE EXCEPTION lx_error.
ENDTRY.
APPEND get_dot_abapgit( )->get_signature( ) TO lt_updated_files.
CLEAR: mt_local, mv_last_serialization.
update_local_checksums( lt_updated_files ).
update_last_deserialize( ).
ENDMETHOD.
METHOD deserialize_checks.
DATA: lt_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt.
find_remote_dot_abapgit( ).
IF get_local_settings( )-write_protected = abap_true.
zcx_abapgit_exception=>raise( 'Cannot deserialize. Local code is write-protected by repo config' ).
ELSEIF get_dot_abapgit( )->get_master_language( ) <> sy-langu.
zcx_abapgit_exception=>raise( 'Current login language does not match master language' ).
ENDIF.
rs_checks = zcl_abapgit_objects=>deserialize_checks( me ).
lt_requirements = get_dot_abapgit( )->get_data( )-requirements.
rs_checks-requirements-met = zcl_abapgit_requirement_helper=>is_requirements_met(
lt_requirements ).
ENDMETHOD.
METHOD find_remote_dot_abapgit.
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF mt_remote.
READ TABLE mt_remote ASSIGNING <ls_remote>
WITH KEY path = zif_abapgit_definitions=>c_root_dir
filename = zif_abapgit_definitions=>c_dot_abapgit.
IF sy-subrc = 0.
ro_dot = zcl_abapgit_dot_abapgit=>deserialize( <ls_remote>-data ).
set_dot_abapgit( ro_dot ).
ENDIF.
ENDMETHOD.
METHOD get_dot_abapgit.
CREATE OBJECT ro_dot_abapgit
EXPORTING
is_data = ms_data-dot_abapgit.
ENDMETHOD.
METHOD get_files_local.
DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt,
ls_item TYPE zif_abapgit_definitions=>ty_item,
lt_files TYPE zif_abapgit_definitions=>ty_files_tt,
lo_progress TYPE REF TO zcl_abapgit_progress,
lt_cache TYPE SORTED TABLE OF zif_abapgit_definitions=>ty_file_item
WITH NON-UNIQUE KEY item.
DATA: lt_filter TYPE SORTED TABLE OF zif_abapgit_definitions=>ty_tadir
WITH NON-UNIQUE KEY object obj_name,
lv_filter_exist TYPE abap_bool.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF lt_files,
<ls_return> LIKE LINE OF rt_files,
<ls_cache> LIKE LINE OF lt_cache,
<ls_tadir> LIKE LINE OF lt_tadir.
" Serialization happened before and no refresh request
IF mv_last_serialization IS NOT INITIAL AND mv_do_local_refresh = abap_false.
rt_files = mt_local.
RETURN.
ENDIF.
APPEND INITIAL LINE TO rt_files ASSIGNING <ls_return>.
<ls_return>-file-path = zif_abapgit_definitions=>c_root_dir.
<ls_return>-file-filename = zif_abapgit_definitions=>c_dot_abapgit.
<ls_return>-file-data = get_dot_abapgit( )->serialize( ).
<ls_return>-file-sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>c_type-blob
iv_data = <ls_return>-file-data ).
lt_cache = mt_local.
lt_tadir = zcl_abapgit_factory=>get_tadir( )->read(
iv_package = get_package( )
iv_ignore_subpackages = get_local_settings( )-ignore_subpackages
iv_only_local_objects = get_local_settings( )-only_local_objects
io_dot = get_dot_abapgit( )
io_log = io_log ).
lt_filter = it_filter.
lv_filter_exist = boolc( lines( lt_filter ) > 0 ).
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( lt_tadir ).
LOOP AT lt_tadir ASSIGNING <ls_tadir>.
IF lv_filter_exist = abap_true.
READ TABLE lt_filter TRANSPORTING NO FIELDS WITH KEY object = <ls_tadir>-object
obj_name = <ls_tadir>-obj_name
BINARY SEARCH.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
ENDIF.
lo_progress->show(
iv_current = sy-tabix
iv_text = |Serialize { <ls_tadir>-obj_name }| ) ##NO_TEXT.
ls_item-obj_type = <ls_tadir>-object.
ls_item-obj_name = <ls_tadir>-obj_name.
ls_item-devclass = <ls_tadir>-devclass.
IF mv_last_serialization IS NOT INITIAL. " Try to fetch from cache
READ TABLE lt_cache TRANSPORTING NO FIELDS
WITH KEY item = ls_item. " type+name+package key
" There is something in cache and the object is unchanged
IF sy-subrc = 0
AND abap_false = zcl_abapgit_objects=>has_changed_since(
is_item = ls_item
iv_timestamp = mv_last_serialization ).
LOOP AT lt_cache ASSIGNING <ls_cache> WHERE item = ls_item.
APPEND <ls_cache> TO rt_files.
ENDLOOP.
CONTINUE.
ENDIF.
ENDIF.
lt_files = zcl_abapgit_objects=>serialize(
is_item = ls_item
iv_language = get_dot_abapgit( )->get_master_language( )
io_log = io_log ).
LOOP AT lt_files ASSIGNING <ls_file>.
<ls_file>-path = <ls_tadir>-path.
APPEND INITIAL LINE TO rt_files ASSIGNING <ls_return>.
<ls_return>-file = <ls_file>.
<ls_return>-item = ls_item.
ENDLOOP.
ENDLOOP.
GET TIME STAMP FIELD mv_last_serialization.
mt_local = rt_files.
mv_do_local_refresh = abap_false. " Fulfill refresh
ENDMETHOD.
METHOD get_files_remote.
rt_files = mt_remote.
ENDMETHOD.
METHOD get_key.
rv_key = ms_data-key.
ENDMETHOD. "get_key
METHOD get_local_checksums.
rt_checksums = ms_data-local_checksums.
ENDMETHOD.
METHOD get_local_checksums_per_file.
FIELD-SYMBOLS <ls_object> LIKE LINE OF ms_data-local_checksums.
LOOP AT ms_data-local_checksums ASSIGNING <ls_object>.
APPEND LINES OF <ls_object>-files TO rt_checksums.
ENDLOOP.
ENDMETHOD.
METHOD get_local_settings.
rs_settings = ms_data-local_settings.
ENDMETHOD.
METHOD get_name.
IF ms_data-offline = abap_true.
rv_name = ms_data-url.
ELSE.
rv_name = zcl_abapgit_url=>name( ms_data-url ).
rv_name = cl_http_utility=>if_http_utility~unescape_url( rv_name ).
ENDIF.
ENDMETHOD. "get_name
METHOD get_package.
rv_package = ms_data-package.
ENDMETHOD. "get_package
METHOD is_offline.
rv_offline = ms_data-offline.
ENDMETHOD.
METHOD rebuild_local_checksums. "LOCAL (BASE)
DATA: lt_local TYPE zif_abapgit_definitions=>ty_files_item_tt,
ls_last_item TYPE zif_abapgit_definitions=>ty_item,
lt_checksums TYPE zif_abapgit_persistence=>ty_local_checksum_tt.
FIELD-SYMBOLS: <ls_checksum> LIKE LINE OF lt_checksums,
<ls_file_sig> LIKE LINE OF <ls_checksum>-files,
<ls_local> LIKE LINE OF lt_local.
lt_local = get_files_local( ).
DELETE lt_local " Remove non-code related files except .abapgit
WHERE item IS INITIAL
AND NOT ( file-path = zif_abapgit_definitions=>c_root_dir
AND file-filename = zif_abapgit_definitions=>c_dot_abapgit ).
SORT lt_local BY item.
LOOP AT lt_local ASSIGNING <ls_local>.
IF ls_last_item <> <ls_local>-item OR sy-tabix = 1. " First or New item reached ?
APPEND INITIAL LINE TO lt_checksums ASSIGNING <ls_checksum>.
<ls_checksum>-item = <ls_local>-item.
ls_last_item = <ls_local>-item.
ENDIF.
APPEND INITIAL LINE TO <ls_checksum>-files ASSIGNING <ls_file_sig>.
MOVE-CORRESPONDING <ls_local>-file TO <ls_file_sig>.
ENDLOOP.
set( it_checksums = lt_checksums ).
ENDMETHOD. " rebuild_local_checksums.
METHOD refresh.
mv_do_local_refresh = abap_true.
IF iv_drop_cache = abap_true.
CLEAR: mv_last_serialization, mt_local.
ENDIF.
ENDMETHOD. "refresh
METHOD run_code_inspector.
DATA: li_code_inspector TYPE REF TO zif_abapgit_code_inspector,
lv_check_variant TYPE string.
lv_check_variant = get_local_settings( )-code_inspector_check_variant.
IF lv_check_variant IS INITIAL.
zcx_abapgit_exception=>raise( |No check variant maintained in repo settings.| ).
ENDIF.
li_code_inspector = zcl_abapgit_factory=>get_code_inspector(
iv_package = get_package( )
iv_check_variant_name = |{ lv_check_variant }| ).
rt_list = li_code_inspector->run( ).
DELETE rt_list WHERE kind = 'N'.
READ TABLE rt_list TRANSPORTING NO FIELDS
WITH KEY kind = 'E'.
mv_code_inspector_successful = boolc( sy-subrc <> 0 ).
ENDMETHOD.
METHOD set.
DATA: li_persistence TYPE REF TO zif_abapgit_persist_repo.
ASSERT it_checksums IS SUPPLIED
OR iv_url IS SUPPLIED
OR iv_branch_name IS SUPPLIED
OR iv_head_branch IS SUPPLIED
OR iv_offline IS SUPPLIED
OR is_dot_abapgit IS SUPPLIED
OR is_local_settings IS SUPPLIED
OR iv_deserialized_by IS SUPPLIED
OR iv_deserialized_at IS SUPPLIED.
li_persistence = zcl_abapgit_persist_factory=>get_repo( ).
IF it_checksums IS SUPPLIED.
li_persistence->update_local_checksums(
iv_key = ms_data-key
it_checksums = it_checksums ).
ms_data-local_checksums = it_checksums.
ENDIF.
IF iv_url IS SUPPLIED.
li_persistence->update_url(
iv_key = ms_data-key
iv_url = iv_url ).
ms_data-url = iv_url.
ENDIF.
IF iv_branch_name IS SUPPLIED.
li_persistence->update_branch_name(
iv_key = ms_data-key
iv_branch_name = iv_branch_name ).
ms_data-branch_name = iv_branch_name.
ENDIF.
IF iv_head_branch IS SUPPLIED.
li_persistence->update_head_branch(
iv_key = ms_data-key
iv_head_branch = iv_head_branch ).
ms_data-head_branch = iv_head_branch.
ENDIF.
IF iv_offline IS SUPPLIED.
li_persistence->update_offline(
iv_key = ms_data-key
iv_offline = iv_offline ).
ms_data-offline = iv_offline.
ENDIF.
IF is_dot_abapgit IS SUPPLIED.
li_persistence->update_dot_abapgit(
iv_key = ms_data-key
is_dot_abapgit = is_dot_abapgit ).
ms_data-dot_abapgit = is_dot_abapgit.
ENDIF.
IF is_local_settings IS SUPPLIED.
li_persistence->update_local_settings(
iv_key = ms_data-key
is_settings = is_local_settings ).
ms_data-local_settings = is_local_settings.
ENDIF.
IF iv_deserialized_at IS SUPPLIED OR iv_deserialized_by IS SUPPLIED.
li_persistence->update_deserialized(
iv_key = ms_data-key
iv_deserialized_at = iv_deserialized_at
iv_deserialized_by = iv_deserialized_by ).
ms_data-deserialized_at = iv_deserialized_at.
ENDIF.
ENDMETHOD.
METHOD set_dot_abapgit.
set( is_dot_abapgit = io_dot_abapgit->get_data( ) ).
ENDMETHOD.
METHOD set_files_remote.
mt_remote = it_files.
ENDMETHOD.
METHOD set_local_settings.
set( is_local_settings = is_settings ).
ENDMETHOD.
METHOD update_last_deserialize.
DATA: lv_deserialized_at TYPE zif_abapgit_persistence=>ty_repo-deserialized_at,
lv_deserialized_by TYPE zif_abapgit_persistence=>ty_repo-deserialized_by.
GET TIME STAMP FIELD lv_deserialized_at.
lv_deserialized_by = sy-uname.
set( iv_deserialized_at = lv_deserialized_at
iv_deserialized_by = lv_deserialized_by ).
ENDMETHOD.
METHOD update_local_checksums.
" ASSUMTION: SHA1 in param is actual and correct.
" Push fills it from local files before pushing, deserialize from remote
" If this is not true that there is an error somewhere but not here
DATA: lt_checksums TYPE zif_abapgit_persistence=>ty_local_checksum_tt,
lt_files_idx TYPE zif_abapgit_definitions=>ty_file_signatures_tt,
lt_local TYPE zif_abapgit_definitions=>ty_files_item_tt,
lv_chks_row TYPE i,
lv_file_row TYPE i.
FIELD-SYMBOLS: <ls_checksum> LIKE LINE OF lt_checksums,
<ls_file> LIKE LINE OF <ls_checksum>-files,
<ls_local> LIKE LINE OF lt_local,
<ls_new_state> LIKE LINE OF it_files.
lt_checksums = get_local_checksums( ).
lt_files_idx = it_files.
SORT lt_files_idx BY path filename. " Sort for binary search
" Loop through current chacksum state, update sha1 for common files
LOOP AT lt_checksums ASSIGNING <ls_checksum>.
lv_chks_row = sy-tabix.
LOOP AT <ls_checksum>-files ASSIGNING <ls_file>.
lv_file_row = sy-tabix.
READ TABLE lt_files_idx ASSIGNING <ls_new_state>
WITH KEY path = <ls_file>-path filename = <ls_file>-filename
BINARY SEARCH.
CHECK sy-subrc = 0. " Missing in param table, skip
IF <ls_new_state>-sha1 IS INITIAL. " Empty input sha1 is a deletion marker
DELETE <ls_checksum>-files INDEX lv_file_row.
ELSE.
<ls_file>-sha1 = <ls_new_state>-sha1. " Update sha1
CLEAR <ls_new_state>-sha1. " Mark as processed
ENDIF.
ENDLOOP.
IF lines( <ls_checksum>-files ) = 0. " Remove empty objects
DELETE lt_checksums INDEX lv_chks_row.
ENDIF.
ENDLOOP.
DELETE lt_files_idx WHERE sha1 IS INITIAL. " Remove processed
IF lines( lt_files_idx ) > 0.
lt_local = get_files_local( ).
SORT lt_local BY file-path file-filename. " Sort for binary search
ENDIF.
" Add new files - not deleted and not marked as processed above
LOOP AT lt_files_idx ASSIGNING <ls_new_state>.
READ TABLE lt_local ASSIGNING <ls_local>
WITH KEY file-path = <ls_new_state>-path file-filename = <ls_new_state>-filename
BINARY SEARCH.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
READ TABLE lt_checksums ASSIGNING <ls_checksum> " TODO Optimize
WITH KEY item = <ls_local>-item.
IF sy-subrc > 0.
APPEND INITIAL LINE TO lt_checksums ASSIGNING <ls_checksum>.
<ls_checksum>-item = <ls_local>-item.
ENDIF.
APPEND <ls_new_state> TO <ls_checksum>-files.
ENDLOOP.
SORT lt_checksums BY item.
set( it_checksums = lt_checksums ).
ENDMETHOD. " update_local_checksums
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECTS_BRIDGE IMPLEMENTATION.
METHOD class_constructor.
DATA lt_plugin_class TYPE STANDARD TABLE OF seoclsname WITH DEFAULT KEY.
DATA lv_plugin_class LIKE LINE OF lt_plugin_class.
DATA lo_plugin TYPE REF TO object.
DATA lt_plugin_obj_type TYPE objtyptable.
DATA ls_objtype_map LIKE LINE OF gt_objtype_map.
SELECT ext~clsname
FROM vseoextend AS ext
INTO TABLE lt_plugin_class
WHERE ext~refclsname LIKE 'ZCL_ABAPGITP_OBJECT%'
AND ext~version = '1'. "#EC CI_SUBRC
CLEAR gt_objtype_map.
LOOP AT lt_plugin_class INTO lv_plugin_class
WHERE table_line <> 'ZCL_ABAPGITP_OBJECT_BY_SOBJ'.
TRY.
CREATE OBJECT lo_plugin TYPE (lv_plugin_class).
CATCH cx_sy_create_object_error.
CONTINUE. ">>>>>>>>>>>>>>
ENDTRY.
CALL METHOD lo_plugin->('GET_SUPPORTED_OBJ_TYPES')
IMPORTING
rt_obj_type = lt_plugin_obj_type.
ls_objtype_map-plugin_class = lv_plugin_class.
LOOP AT lt_plugin_obj_type INTO ls_objtype_map-obj_typ.
INSERT ls_objtype_map INTO TABLE gt_objtype_map.
IF sy-subrc <> 0.
ASSERT 'There must not be' =
|multiple abapGit-Plugins for the same object type {
ls_objtype_map-obj_typ }|.
ENDIF.
ENDLOOP.
ENDLOOP. "at plugins
LOOP AT lt_plugin_class INTO lv_plugin_class
WHERE table_line = 'ZCL_ABAPGITP_OBJECT_BY_SOBJ'.
CREATE OBJECT lo_plugin TYPE (lv_plugin_class).
CALL METHOD lo_plugin->('GET_SUPPORTED_OBJ_TYPES')
RECEIVING
rt_obj_type = lt_plugin_obj_type.
ls_objtype_map-plugin_class = lv_plugin_class.
LOOP AT lt_plugin_obj_type INTO ls_objtype_map-obj_typ.
INSERT ls_objtype_map INTO TABLE gt_objtype_map. "knowingly ignore the subrc
ENDLOOP.
ENDLOOP. "at plugins
ENDMETHOD. "class_constructor
METHOD constructor.
DATA ls_objtype_map LIKE LINE OF gt_objtype_map.
super->constructor( is_item = is_item
iv_language = zif_abapgit_definitions=>c_english ).
READ TABLE gt_objtype_map INTO ls_objtype_map
WITH TABLE KEY obj_typ = is_item-obj_type.
IF sy-subrc = 0.
CREATE OBJECT mo_plugin TYPE (ls_objtype_map-plugin_class).
CALL METHOD mo_plugin->('SET_ITEM')
EXPORTING
iv_obj_type = is_item-obj_type
iv_obj_name = is_item-obj_name.
ELSE.
RAISE EXCEPTION TYPE cx_sy_create_object_error
EXPORTING
classname = 'LCL_OBJECTS_BRIDGE'.
ENDIF.
ENDMETHOD. "constructor
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA lx_plugin TYPE REF TO cx_static_check.
TRY.
CALL METHOD mo_plugin->('ZIF_ABAPGITP_PLUGIN~DELETE').
CATCH cx_static_check INTO lx_plugin.
zcx_abapgit_exception=>raise( lx_plugin->get_text( ) ).
ENDTRY.
ENDMETHOD. "lif_object~delete
METHOD zif_abapgit_object~deserialize.
DATA: lx_plugin TYPE REF TO cx_static_check.
TRY.
CALL METHOD mo_plugin->('WRAP_DESERIALIZE')
EXPORTING
iv_package = iv_package
io_xml = io_xml.
CATCH cx_static_check INTO lx_plugin.
zcx_abapgit_exception=>raise( lx_plugin->get_text( ) ).
ENDTRY.
ENDMETHOD. "lif_object~deserialize
METHOD zif_abapgit_object~exists.
CALL METHOD mo_plugin->('ZIF_ABAPGITP_PLUGIN~EXISTS')
RECEIVING
rv_bool = rv_bool.
ENDMETHOD. "lif_object~exists
METHOD zif_abapgit_object~get_metadata.
CALL METHOD mo_plugin->('ZIF_ABAPGITP_PLUGIN~GET_METADATA')
RECEIVING
rs_metadata = rs_metadata.
ENDMETHOD. "lif_object~get_metadata
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD. "lif_object~has_changed_since
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL METHOD mo_plugin->('ZIF_ABAPGITP_PLUGIN~JUMP').
ENDMETHOD. "lif_object~jump
METHOD zif_abapgit_object~serialize.
CALL METHOD mo_plugin->('WRAP_SERIALIZE')
EXPORTING
io_xml = io_xml.
ENDMETHOD. "lif_object~serialize
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECTS IMPLEMENTATION.
METHOD changed_by.
DATA: li_obj TYPE REF TO zif_abapgit_object.
IF is_item IS INITIAL.
rv_user = zcl_abapgit_objects_super=>c_user_unknown.
ELSE.
li_obj = create_object( is_item = is_item
iv_language = zif_abapgit_definitions=>c_english ).
rv_user = li_obj->changed_by( ).
ENDIF.
ASSERT NOT rv_user IS INITIAL.
ENDMETHOD.
METHOD checks_adjust.
warning_overwrite_adjust(
EXPORTING it_overwrite = is_checks-overwrite
CHANGING ct_results = ct_results ).
warning_package_adjust(
EXPORTING
io_repo = io_repo
it_overwrite = is_checks-warning_package
CHANGING
ct_results = ct_results ).
ENDMETHOD.
METHOD check_duplicates.
DATA: lt_files TYPE zif_abapgit_definitions=>ty_files_tt.
lt_files = it_files.
SORT lt_files BY path ASCENDING filename ASCENDING.
DELETE ADJACENT DUPLICATES FROM lt_files COMPARING path filename.
IF lines( lt_files ) <> lines( it_files ).
zcx_abapgit_exception=>raise( 'Duplicates' ).
ENDIF.
ENDMETHOD.
METHOD check_objects_locked.
DATA: li_obj TYPE REF TO zif_abapgit_object.
FIELD-SYMBOLS: <ls_item> LIKE LINE OF it_items.
LOOP AT it_items ASSIGNING <ls_item>.
li_obj = create_object( is_item = <ls_item>
iv_language = iv_language ).
IF li_obj->is_locked( ) = abap_true.
zcx_abapgit_exception=>raise( |Object { <ls_item>-obj_type } { <ls_item>-obj_name } |
&& |is locked. Action not possible.| ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD class_name.
CONCATENATE 'ZCL_ABAPGIT_OBJECT_' is_item-obj_type INTO rv_class_name. "#EC NOTEXT
ENDMETHOD. "class_name
METHOD compare_remote_to_local.
DATA: ls_remote_file TYPE zif_abapgit_definitions=>ty_file,
lo_remote_version TYPE REF TO zcl_abapgit_xml_input,
lv_count TYPE i,
li_comparison_result TYPE REF TO zif_abapgit_comparison_result.
FIND ALL OCCURRENCES OF '.' IN is_result-filename MATCH COUNT lv_count.
IF is_result-filename CS '.XML' AND lv_count = 2.
IF ii_object->exists( ) = abap_false.
RETURN.
ENDIF.
READ TABLE it_remote WITH KEY filename = is_result-filename INTO ls_remote_file.
"if file does not exist in remote, we don't need to validate
IF sy-subrc = 0.
CREATE OBJECT lo_remote_version
EXPORTING
iv_xml = zcl_abapgit_convert=>xstring_to_string_utf8( ls_remote_file-data ).
li_comparison_result = ii_object->compare_to_remote_version( lo_remote_version ).
li_comparison_result->show_confirmation_dialog( ).
IF li_comparison_result->is_result_complete_halt( ) = abap_true.
zcx_abapgit_exception=>raise( 'Deserialization aborted by user' ).
ENDIF.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD create_object.
DATA: lv_message TYPE string,
lv_class_name TYPE string,
ls_obj_serializer_map LIKE LINE OF gt_obj_serializer_map.
READ TABLE gt_obj_serializer_map
INTO ls_obj_serializer_map WITH KEY item = is_item.
IF sy-subrc = 0.
lv_class_name = ls_obj_serializer_map-metadata-class.
ELSEIF is_metadata IS NOT INITIAL.
ls_obj_serializer_map-item = is_item.
ls_obj_serializer_map-metadata = is_metadata.
INSERT ls_obj_serializer_map INTO TABLE gt_obj_serializer_map.
lv_class_name = is_metadata-class.
ELSE.
lv_class_name = class_name( is_item ).
ENDIF.
REPLACE FIRST OCCURRENCE OF 'LCL' IN lv_class_name WITH 'ZCL_ABAPGIT'.
TRY.
CREATE OBJECT ri_obj TYPE (lv_class_name)
EXPORTING
is_item = is_item
iv_language = iv_language.
CATCH cx_sy_create_object_error.
lv_message = |Object type { is_item-obj_type } not supported, serialize|. "#EC NOTEXT
IF iv_native_only = abap_false.
TRY. " 2nd step, try looking for plugins
CREATE OBJECT ri_obj TYPE zcl_abapgit_objects_bridge
EXPORTING
is_item = is_item.
CATCH cx_sy_create_object_error.
zcx_abapgit_exception=>raise( lv_message ).
ENDTRY.
ELSE. " No native support? -> fail
zcx_abapgit_exception=>raise( lv_message ).
ENDIF.
ENDTRY.
ENDMETHOD. "create_object
METHOD delete.
DATA: ls_item TYPE zif_abapgit_definitions=>ty_item,
lo_progress TYPE REF TO zcl_abapgit_progress,
lt_tadir LIKE it_tadir,
lt_items TYPE zif_abapgit_definitions=>ty_items_tt,
lx_error TYPE REF TO zcx_abapgit_exception,
lv_text TYPE string.
FIELD-SYMBOLS: <ls_tadir> LIKE LINE OF it_tadir.
lt_tadir = it_tadir.
IF is_checks-transport-required = abap_true.
zcl_abapgit_default_transport=>get_instance( )->set( is_checks-transport-transport ).
ENDIF.
TRY.
zcl_abapgit_dependencies=>resolve( CHANGING ct_tadir = lt_tadir ).
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( lt_tadir ).
lt_items = map_tadir_to_items( lt_tadir ).
check_objects_locked( iv_language = zif_abapgit_definitions=>c_english
it_items = lt_items ).
LOOP AT lt_tadir ASSIGNING <ls_tadir>.
lo_progress->show( iv_current = sy-tabix
iv_text = |Delete { <ls_tadir>-obj_name }| ) ##NO_TEXT.
CLEAR ls_item.
ls_item-obj_type = <ls_tadir>-object.
ls_item-obj_name = <ls_tadir>-obj_name.
delete_obj( ls_item ).
COMMIT WORK.
ENDLOOP.
CATCH zcx_abapgit_exception INTO lx_error.
zcl_abapgit_default_transport=>get_instance( )->reset( ).
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
zcl_abapgit_default_transport=>get_instance( )->reset( ).
ENDMETHOD. "delete
METHOD delete_obj.
DATA: li_obj TYPE REF TO zif_abapgit_object.
IF is_supported( is_item ) = abap_true.
li_obj = create_object( is_item = is_item
iv_language = zif_abapgit_definitions=>c_english ).
li_obj->delete( ).
IF li_obj->get_metadata( )-delete_tadir = abap_true.
CALL FUNCTION 'TR_TADIR_INTERFACE'
EXPORTING
wi_delete_tadir_entry = abap_true
wi_tadir_pgmid = 'R3TR'
wi_tadir_object = is_item-obj_type
wi_tadir_obj_name = is_item-obj_name
wi_test_modus = abap_false.
ENDIF.
ENDIF.
ENDMETHOD. "delete
METHOD deserialize.
DATA: ls_item TYPE zif_abapgit_definitions=>ty_item,
li_obj TYPE REF TO zif_abapgit_object,
lt_remote TYPE zif_abapgit_definitions=>ty_files_tt,
lv_package TYPE devclass,
lo_files TYPE REF TO zcl_abapgit_objects_files,
lo_xml TYPE REF TO zcl_abapgit_xml_input,
lt_results TYPE zif_abapgit_definitions=>ty_results_tt,
lt_ddic TYPE TABLE OF ty_deserialization,
lt_rest TYPE TABLE OF ty_deserialization,
lt_late TYPE TABLE OF ty_deserialization,
lo_progress TYPE REF TO zcl_abapgit_progress,
lv_path TYPE string,
lt_items TYPE zif_abapgit_definitions=>ty_items_tt.
DATA: lo_folder_logic TYPE REF TO zcl_abapgit_folder_logic.
FIELD-SYMBOLS: <ls_result> TYPE zif_abapgit_definitions=>ty_result,
<ls_deser> LIKE LINE OF lt_late.
lv_package = io_repo->get_package( ).
IF is_checks-transport-required = abap_true.
zcl_abapgit_default_transport=>get_instance( )->set( is_checks-transport-transport ).
ENDIF.
zcl_abapgit_objects_activation=>clear( ).
lt_remote = io_repo->get_files_remote( ).
lt_results = files_to_deserialize( io_repo ).
checks_adjust(
EXPORTING
io_repo = io_repo
is_checks = is_checks
CHANGING
ct_results = lt_results ).
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( lt_results ).
lt_items = map_results_to_items( lt_results ).
check_objects_locked( iv_language = io_repo->get_dot_abapgit( )->get_master_language( )
it_items = lt_items ).
lo_folder_logic = zcl_abapgit_folder_logic=>get_instance( ).
LOOP AT lt_results ASSIGNING <ls_result>.
lo_progress->show( iv_current = sy-tabix
iv_text = |Deserialize { <ls_result>-obj_name }| ) ##NO_TEXT.
CLEAR ls_item.
ls_item-obj_type = <ls_result>-obj_type.
ls_item-obj_name = <ls_result>-obj_name.
lv_package = lo_folder_logic->path_to_package(
iv_top = io_repo->get_package( )
io_dot = io_repo->get_dot_abapgit( )
iv_path = <ls_result>-path ).
IF ls_item-obj_type = 'DEVC'.
" Packages have the same filename across different folders. The path needs to be supplied
" to find the correct file.
lv_path = <ls_result>-path.
ENDIF.
CREATE OBJECT lo_files
EXPORTING
is_item = ls_item
iv_path = lv_path.
lo_files->set_files( lt_remote ).
lo_xml = lo_files->read_xml( ).
li_obj = create_object( is_item = ls_item
iv_language = io_repo->get_dot_abapgit( )->get_master_language( )
is_metadata = lo_xml->get_metadata( ) ).
compare_remote_to_local(
ii_object = li_obj
it_remote = lt_remote
is_result = <ls_result> ).
li_obj->mo_files = lo_files.
IF li_obj->get_metadata( )-late_deser = abap_true.
APPEND INITIAL LINE TO lt_late ASSIGNING <ls_deser>.
ELSEIF li_obj->get_metadata( )-ddic = abap_true.
APPEND INITIAL LINE TO lt_ddic ASSIGNING <ls_deser>.
ELSE.
APPEND INITIAL LINE TO lt_rest ASSIGNING <ls_deser>.
ENDIF.
<ls_deser>-item = ls_item.
<ls_deser>-obj = li_obj.
<ls_deser>-xml = lo_xml.
<ls_deser>-package = lv_package.
CLEAR: lv_path, lv_package.
ENDLOOP.
deserialize_objects( EXPORTING it_objects = lt_ddic
iv_ddic = abap_true
iv_descr = 'DDIC'
CHANGING ct_files = rt_accessed_files ).
deserialize_objects( EXPORTING it_objects = lt_rest
iv_descr = 'Objects'
CHANGING ct_files = rt_accessed_files ).
deserialize_objects( EXPORTING it_objects = lt_late
iv_descr = 'Late'
CHANGING ct_files = rt_accessed_files ).
update_package_tree( io_repo->get_package( ) ).
SORT rt_accessed_files BY path ASCENDING filename ASCENDING.
DELETE ADJACENT DUPLICATES FROM rt_accessed_files. " Just in case
zcl_abapgit_default_transport=>get_instance( )->reset( ).
ENDMETHOD. "deserialize
METHOD deserialize_checks.
DATA: lt_results TYPE zif_abapgit_definitions=>ty_results_tt,
li_package TYPE REF TO zif_abapgit_sap_package.
lt_results = files_to_deserialize( io_repo ).
rs_checks-overwrite = warning_overwrite_find( lt_results ).
rs_checks-warning_package = warning_package_find(
io_repo = io_repo
it_results = lt_results ).
IF lines( lt_results ) > 0.
li_package = zcl_abapgit_factory=>get_sap_package( io_repo->get_package( ) ).
rs_checks-transport-required = li_package->are_changes_recorded_in_tr_req( ).
IF NOT rs_checks-transport-required IS INITIAL.
rs_checks-transport-type = li_package->get_transport_type( ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD deserialize_objects.
DATA: lo_progress TYPE REF TO zcl_abapgit_progress.
FIELD-SYMBOLS: <ls_obj> LIKE LINE OF it_objects.
zcl_abapgit_objects_activation=>clear( ).
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( it_objects ).
LOOP AT it_objects ASSIGNING <ls_obj>.
lo_progress->show(
iv_current = sy-tabix
iv_text = |Deserialize { iv_descr } - { <ls_obj>-item-obj_name }| ) ##NO_TEXT.
<ls_obj>-obj->deserialize( iv_package = <ls_obj>-package
io_xml = <ls_obj>-xml ).
APPEND LINES OF <ls_obj>-obj->mo_files->get_accessed_files( ) TO ct_files.
ENDLOOP.
zcl_abapgit_objects_activation=>activate( iv_ddic ).
ENDMETHOD.
METHOD exists.
DATA: li_obj TYPE REF TO zif_abapgit_object.
TRY.
li_obj = create_object( is_item = is_item
iv_language = zif_abapgit_definitions=>c_english ).
rv_bool = li_obj->exists( ).
CATCH zcx_abapgit_exception.
rv_bool = abap_true.
ENDTRY.
ENDMETHOD. "exists
METHOD files_to_deserialize.
FIELD-SYMBOLS: <ls_result> LIKE LINE OF rt_results.
rt_results = zcl_abapgit_file_status=>status( io_repo ).
DELETE rt_results WHERE match = abap_true. " Full match
SORT rt_results
BY obj_type ASCENDING
obj_name ASCENDING
filename ASCENDING.
DELETE ADJACENT DUPLICATES FROM rt_results COMPARING obj_type obj_name filename.
DELETE rt_results WHERE obj_type IS INITIAL.
DELETE rt_results WHERE lstate = zif_abapgit_definitions=>c_state-added AND rstate IS INITIAL.
rt_results = prioritize_deser( rt_results ).
LOOP AT rt_results ASSIGNING <ls_result>.
REPLACE ALL OCCURRENCES OF '#' IN <ls_result>-obj_name WITH '/'.
ENDLOOP.
ENDMETHOD.
METHOD has_changed_since.
rv_changed = abap_true. " Assume changed
IF is_supported( is_item ) = abap_false.
RETURN. " Will requre serialize which will log the error
ENDIF.
rv_changed = create_object(
is_item = is_item
iv_language = zif_abapgit_definitions=>c_english )->has_changed_since( iv_timestamp ).
ENDMETHOD. "has_changed_since
METHOD is_supported.
TRY.
create_object( is_item = is_item
iv_language = zif_abapgit_definitions=>c_english
iv_native_only = iv_native_only ).
rv_bool = abap_true.
CATCH zcx_abapgit_exception.
rv_bool = abap_false.
ENDTRY.
ENDMETHOD. "is_supported
METHOD jump.
DATA: li_obj TYPE REF TO zif_abapgit_object,
lv_adt_jump_enabled TYPE abap_bool.
li_obj = create_object( is_item = is_item
iv_language = zif_abapgit_definitions=>c_english ).
lv_adt_jump_enabled = zcl_abapgit_persist_settings=>get_instance( )->read( )->get_adt_jump_enabled( ).
IF lv_adt_jump_enabled = abap_true.
TRY.
zcl_abapgit_objects_super=>jump_adt(
i_obj_name = is_item-obj_name
i_obj_type = is_item-obj_type ).
CATCH zcx_abapgit_exception.
li_obj->jump( ).
ENDTRY.
ELSE.
li_obj->jump( ).
ENDIF.
ENDMETHOD. "jump
METHOD map_results_to_items.
DATA: ls_item LIKE LINE OF rt_items.
FIELD-SYMBOLS: <ls_result> TYPE zif_abapgit_definitions=>ty_result.
LOOP AT it_results ASSIGNING <ls_result>.
ls_item-devclass = <ls_result>-package.
ls_item-obj_type = <ls_result>-obj_type.
ls_item-obj_name = <ls_result>-obj_name.
INSERT ls_item INTO TABLE rt_items.
ENDLOOP.
ENDMETHOD.
METHOD map_tadir_to_items.
DATA: ls_item LIKE LINE OF rt_items.
FIELD-SYMBOLS: <ls_tadir> TYPE zif_abapgit_definitions=>ty_tadir.
LOOP AT it_tadir ASSIGNING <ls_tadir>.
ls_item-devclass = <ls_tadir>-devclass.
ls_item-obj_type = <ls_tadir>-object.
ls_item-obj_name = <ls_tadir>-obj_name.
INSERT ls_item INTO TABLE rt_items.
ENDLOOP.
ENDMETHOD.
METHOD prioritize_deser.
FIELD-SYMBOLS: <ls_result> LIKE LINE OF it_results.
LOOP AT it_results ASSIGNING <ls_result> WHERE obj_type = 'XSLT'.
APPEND <ls_result> TO rt_results.
ENDLOOP.
LOOP AT it_results ASSIGNING <ls_result> WHERE obj_type = 'PROG'.
APPEND <ls_result> TO rt_results.
ENDLOOP.
LOOP AT it_results ASSIGNING <ls_result> WHERE obj_type = 'IASP'.
APPEND <ls_result> TO rt_results.
ENDLOOP.
LOOP AT it_results ASSIGNING <ls_result> WHERE obj_type = 'PINF'.
APPEND <ls_result> TO rt_results.
ENDLOOP.
LOOP AT it_results ASSIGNING <ls_result> WHERE obj_type = 'ENHS'.
APPEND <ls_result> TO rt_results.
ENDLOOP.
LOOP AT it_results ASSIGNING <ls_result>
WHERE obj_type <> 'IASP'
AND obj_type <> 'PROG'
AND obj_type <> 'XSLT'
AND obj_type <> 'PINF'
AND obj_type <> 'ENHS'.
APPEND <ls_result> TO rt_results.
ENDLOOP.
ENDMETHOD. "prioritize_deser
METHOD serialize.
DATA: li_obj TYPE REF TO zif_abapgit_object,
lo_xml TYPE REF TO zcl_abapgit_xml_output,
lo_files TYPE REF TO zcl_abapgit_objects_files.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF rt_files.
IF is_supported( is_item ) = abap_false.
IF NOT io_log IS INITIAL.
io_log->add( iv_msg = |Object type ignored, not supported: { is_item-obj_type
}-{ is_item-obj_name }|
iv_type = 'E' ).
ENDIF.
RETURN.
ENDIF.
CREATE OBJECT lo_files
EXPORTING
is_item = is_item.
li_obj = create_object( is_item = is_item
iv_language = iv_language ).
li_obj->mo_files = lo_files.
CREATE OBJECT lo_xml.
li_obj->serialize( lo_xml ).
lo_files->add_xml( io_xml = lo_xml
is_metadata = li_obj->get_metadata( ) ).
rt_files = lo_files->get_files( ).
check_duplicates( rt_files ).
LOOP AT rt_files ASSIGNING <ls_file>.
<ls_file>-sha1 = zcl_abapgit_hash=>sha1(
iv_type = zif_abapgit_definitions=>c_type-blob
iv_data = <ls_file>-data ).
ENDLOOP.
ENDMETHOD.
METHOD supported_list.
DATA: lt_objects TYPE STANDARD TABLE OF ko100,
lv_supported TYPE abap_bool,
ls_item TYPE zif_abapgit_definitions=>ty_item.
FIELD-SYMBOLS <ls_object> LIKE LINE OF lt_objects.
CALL FUNCTION 'TR_OBJECT_TABLE'
TABLES
wt_object_text = lt_objects
EXCEPTIONS
OTHERS = 1 ##FM_SUBRC_OK.
LOOP AT lt_objects ASSIGNING <ls_object> WHERE pgmid = 'R3TR'.
ls_item-obj_type = <ls_object>-object.
lv_supported = zcl_abapgit_objects=>is_supported(
is_item = ls_item
iv_native_only = abap_true ).
IF lv_supported = abap_true.
APPEND <ls_object>-object TO rt_types.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD update_package_tree.
DATA: lt_packages TYPE zif_abapgit_sap_package=>ty_devclass_tt,
lv_package LIKE LINE OF lt_packages,
lv_tree TYPE dirtree-tname.
lt_packages = zcl_abapgit_factory=>get_sap_package( iv_package )->list_subpackages( ).
APPEND iv_package TO lt_packages.
LOOP AT lt_packages INTO lv_package.
lv_tree = 'EU_' && lv_package.
CALL FUNCTION 'WB_TREE_ACTUALIZE'
EXPORTING
tree_name = lv_tree
without_crossreference = abap_true
with_tcode_index = abap_true.
ENDLOOP.
ENDMETHOD. "update_package_tree
METHOD warning_overwrite_adjust.
DATA: lt_overwrite LIKE it_overwrite,
ls_overwrite LIKE LINE OF lt_overwrite.
FIELD-SYMBOLS: <ls_overwrite> LIKE LINE OF lt_overwrite.
lt_overwrite = warning_overwrite_find( ct_results ).
LOOP AT lt_overwrite ASSIGNING <ls_overwrite>.
READ TABLE it_overwrite INTO ls_overwrite WITH KEY
obj_type = <ls_overwrite>-obj_type
obj_name = <ls_overwrite>-obj_name.
IF sy-subrc <> 0 OR ls_overwrite-decision IS INITIAL.
zcx_abapgit_exception=>raise( |Overwrite { <ls_overwrite>-obj_type } {
<ls_overwrite>-obj_name } undecided| ).
ENDIF.
IF ls_overwrite-decision = 'N'.
DELETE ct_results WHERE
obj_type = <ls_overwrite>-obj_type AND
obj_name = <ls_overwrite>-obj_name.
ASSERT sy-subrc = 0.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD warning_overwrite_find.
DATA: ls_overwrite LIKE LINE OF rt_overwrite.
FIELD-SYMBOLS: <ls_result> LIKE LINE OF it_results.
LOOP AT it_results ASSIGNING <ls_result>
WHERE NOT obj_type IS INITIAL.
IF <ls_result>-lstate IS NOT INITIAL
AND <ls_result>-lstate <> zif_abapgit_definitions=>c_state-deleted
AND NOT ( <ls_result>-lstate = zif_abapgit_definitions=>c_state-added
AND <ls_result>-rstate IS INITIAL ).
CLEAR ls_overwrite.
MOVE-CORRESPONDING <ls_result> TO ls_overwrite.
APPEND ls_overwrite TO rt_overwrite.
ENDIF.
ENDLOOP.
SORT rt_overwrite.
DELETE ADJACENT DUPLICATES FROM rt_overwrite.
ENDMETHOD.
METHOD warning_package_adjust.
DATA: lt_overwrite LIKE it_overwrite,
ls_overwrite LIKE LINE OF lt_overwrite.
FIELD-SYMBOLS: <ls_overwrite> LIKE LINE OF lt_overwrite.
lt_overwrite = warning_package_find(
it_results = ct_results
io_repo = io_repo ).
LOOP AT lt_overwrite ASSIGNING <ls_overwrite>.
READ TABLE it_overwrite INTO ls_overwrite WITH KEY
obj_type = <ls_overwrite>-obj_type
obj_name = <ls_overwrite>-obj_name.
IF sy-subrc <> 0 OR ls_overwrite-decision IS INITIAL.
zcx_abapgit_exception=>raise( |Overwrite odd package { <ls_overwrite>-obj_type } {
<ls_overwrite>-obj_name } undecided| ).
ENDIF.
IF ls_overwrite-decision = 'N'.
DELETE ct_results WHERE
obj_type = <ls_overwrite>-obj_type AND
obj_name = <ls_overwrite>-obj_name.
ASSERT sy-subrc = 0.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD warning_package_find.
DATA: lv_package TYPE devclass,
lt_overwrite_uniqe TYPE HASHED TABLE OF zif_abapgit_definitions=>ty_overwrite
WITH UNIQUE KEY obj_type obj_name devclass,
ls_overwrite LIKE LINE OF rt_overwrite,
ls_tadir TYPE zif_abapgit_definitions=>ty_tadir.
DATA: lo_folder_logic TYPE REF TO zcl_abapgit_folder_logic.
FIELD-SYMBOLS: <ls_result> LIKE LINE OF it_results.
lo_folder_logic = zcl_abapgit_folder_logic=>get_instance( ).
LOOP AT it_results ASSIGNING <ls_result>.
lv_package = lo_folder_logic->path_to_package(
iv_top = io_repo->get_package( )
io_dot = io_repo->get_dot_abapgit( )
iv_path = <ls_result>-path ).
ls_tadir = zcl_abapgit_factory=>get_tadir( )->read_single(
iv_object = <ls_result>-obj_type
iv_obj_name = <ls_result>-obj_name ).
IF NOT ls_tadir IS INITIAL AND ls_tadir-devclass <> lv_package.
CLEAR ls_overwrite.
ls_overwrite-obj_type = <ls_result>-obj_type.
ls_overwrite-obj_name = <ls_result>-obj_name.
ls_overwrite-devclass = ls_tadir-devclass.
INSERT ls_overwrite INTO TABLE lt_overwrite_uniqe.
ENDIF.
ENDLOOP.
rt_overwrite = lt_overwrite_uniqe.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_NEWS IMPLEMENTATION.
METHOD compare_versions.
DATA: lv_version_a TYPE i,
lv_version_b TYPE i.
" Convert versions to numeric
lv_version_a = version_to_numeric( iv_a ).
lv_version_b = version_to_numeric( iv_b ).
" Compare versions
IF lv_version_a > lv_version_b.
rv_result = 1.
ELSEIF lv_version_a < lv_version_b.
rv_result = -1.
ELSE.
rv_result = 0.
ENDIF.
ENDMETHOD. "compare_versions
METHOD constructor.
DATA: lt_lines TYPE string_table,
lv_string TYPE string,
ls_log_line LIKE LINE OF mt_log.
" Validate params
mv_current_version = normalize_version( iv_current_version ).
mv_lastseen_version = normalize_version( iv_lastseen_version ).
IF mv_current_version IS INITIAL.
RETURN. " Internal format of program version is not correct -> abort parsing
ENDIF.
lv_string = zcl_abapgit_convert=>xstring_to_string_utf8( iv_rawdata ).
lt_lines = zcl_abapgit_convert=>split_string( lv_string ).
mt_log = parse( it_lines = lt_lines iv_current_version = mv_current_version ).
READ TABLE mt_log INTO ls_log_line INDEX 1.
mv_latest_version = ls_log_line-version. " Empty if not found
ENDMETHOD. "constructor
METHOD create.
" TODO REFACTOR !
CONSTANTS: " TODO refactor
lc_log_path TYPE string VALUE '/',
lc_log_filename TYPE string VALUE 'changelog.txt'.
DATA: lt_remote TYPE zif_abapgit_definitions=>ty_files_tt,
lv_last_seen TYPE string,
lv_url TYPE string,
lo_repo_online TYPE REF TO zcl_abapgit_repo_online.
FIELD-SYMBOLS <ls_file> LIKE LINE OF lt_remote.
IF io_repo->is_offline( ) = abap_true.
RETURN.
ENDIF.
lo_repo_online ?= io_repo.
lv_url = lo_repo_online->get_url( ).
IF is_relevant( lv_url ) = abap_false.
RETURN.
ENDIF.
lv_last_seen = zcl_abapgit_persistence_user=>get_instance( )->get_repo_last_change_seen( lv_url ).
TRY.
" Find changelog
lt_remote = io_repo->get_files_remote( ).
CATCH zcx_abapgit_exception.
RETURN.
ENDTRY.
READ TABLE lt_remote ASSIGNING <ls_file>
WITH KEY path = lc_log_path filename = lc_log_filename.
IF sy-subrc = 0.
CREATE OBJECT ro_instance
EXPORTING
iv_rawdata = <ls_file>-data
iv_current_version = zif_abapgit_version=>gc_abap_version " TODO refactor
iv_lastseen_version = normalize_version( lv_last_seen ).
ENDIF.
IF ro_instance IS BOUND AND lv_last_seen <> ro_instance->latest_version( ).
zcl_abapgit_persistence_user=>get_instance( )->set_repo_last_change_seen(
iv_url = lv_url
iv_version = ro_instance->latest_version( ) ).
ENDIF.
ENDMETHOD. "create
METHOD get_log.
rt_log = me->mt_log.
ENDMETHOD. "get_log
METHOD has_important.
READ TABLE mt_log WITH KEY is_important = abap_true TRANSPORTING NO FIELDS.
rv_boolean = boolc( sy-subrc IS INITIAL ).
ENDMETHOD. "has_important_news
METHOD has_news.
rv_boolean = boolc( lines( mt_log ) > 0 ).
ENDMETHOD. "has_news
METHOD has_unseen.
rv_boolean = boolc( compare_versions(
iv_a = mv_latest_version
iv_b = mv_lastseen_version ) > 0 ).
ENDMETHOD. "has_unseen
METHOD has_updates.
rv_boolean = boolc( compare_versions(
iv_a = mv_latest_version
iv_b = mv_current_version ) > 0 ).
ENDMETHOD. "has_updates
METHOD is_relevant.
" News announcement restricted to abapGit only
IF iv_url CS '/abapGit' OR iv_url CS '/abapGit.git'.
rv_relevant = abap_true.
ENDIF.
ENDMETHOD.
METHOD latest_version.
rv_version = me->mv_latest_version.
ENDMETHOD. "latest_version
METHOD normalize_version.
" Internal program version should be in format "XXX.XXX.XXX" or "vXXX.XXX.XXX"
CONSTANTS: lc_version_pattern TYPE string VALUE '^v?(\d{1,3}\.\d{1,3}\.\d{1,3})\s*$'.
FIND FIRST OCCURRENCE OF REGEX lc_version_pattern
IN iv_version SUBMATCHES rv_version.
ENDMETHOD. "normalize_version
METHOD parse.
DATA: lv_tail TYPE i,
lv_first_version_found TYPE abap_bool,
lv_version TYPE string,
ls_log LIKE LINE OF rt_log.
FIELD-SYMBOLS: <lv_line> LIKE LINE OF it_lines.
LOOP AT it_lines ASSIGNING <lv_line>.
ls_log = parse_line( iv_line = <lv_line> iv_current_version = iv_current_version ).
" Skip until first version head and Skip empty lines
CHECK ls_log IS NOT INITIAL AND
( lv_first_version_found = abap_true OR ls_log-version IS NOT INITIAL ).
IF lv_first_version_found = abap_false.
lv_first_version_found = abap_true.
IF compare_versions( iv_a = ls_log-version iv_b = iv_current_version ) <= 0.
lv_tail = c_tail_length. " Display some last versions if no updates
ENDIF.
ENDIF.
IF ls_log-is_header = abap_true.
"Skip everything below current version or show tail news
IF compare_versions( iv_a = ls_log-version iv_b = iv_current_version ) <= 0.
IF lv_tail > 0.
lv_tail = lv_tail - 1.
ELSE.
EXIT.
ENDIF.
ENDIF.
lv_version = ls_log-version. " Save to fill news lines
ELSE.
ls_log-version = lv_version.
ENDIF.
APPEND ls_log TO rt_log.
ENDLOOP.
ENDMETHOD. "parse
METHOD parse_line.
CONSTANTS: lc_header_pattern TYPE string
VALUE '^\d{4}-\d{2}-\d{2}\s+v(\d{1,3}\.\d{1,3}\.\d{1,3})\s*$'.
DATA: lv_version TYPE string.
IF iv_line IS INITIAL OR iv_line CO ' -='.
RETURN. " Skip empty and markup lines
ENDIF.
" Check if line is a header line
FIND FIRST OCCURRENCE OF REGEX lc_header_pattern IN iv_line SUBMATCHES lv_version.
IF sy-subrc IS INITIAL.
lv_version = normalize_version( lv_version ).
rs_log-version = lv_version.
rs_log-is_header = abap_true.
rs_log-pos_to_cur = compare_versions( iv_a = lv_version iv_b = iv_current_version ).
ELSE.
FIND FIRST OCCURRENCE OF REGEX '^\s*!' IN iv_line.
rs_log-is_important = boolc( sy-subrc IS INITIAL ). " Change is important
ENDIF.
rs_log-text = iv_line.
ENDMETHOD. "parse_line
METHOD version_to_numeric.
DATA: lv_major TYPE numc4,
lv_minor TYPE numc4,
lv_release TYPE numc4.
SPLIT iv_version AT '.' INTO lv_major lv_minor lv_release.
" Calculated value of version number, empty version will become 0 which is OK
rv_version = lv_major * 1000000 + lv_minor * 1000 + lv_release.
ENDMETHOD. "convert_version_to_numeric
ENDCLASS.
CLASS ZCL_ABAPGIT_MIGRATIONS IMPLEMENTATION.
METHOD local_dot_abapgit.
DATA: lt_repos TYPE zif_abapgit_definitions=>ty_repo_ref_tt,
lo_dot_abapgit TYPE REF TO zcl_abapgit_dot_abapgit.
FIELD-SYMBOLS: <lo_repo> LIKE LINE OF lt_repos.
lt_repos = zcl_abapgit_repo_srv=>get_instance( )->list( ).
LOOP AT lt_repos ASSIGNING <lo_repo>.
lo_dot_abapgit = <lo_repo>->get_dot_abapgit( ).
IF lo_dot_abapgit->get_data( ) IS INITIAL.
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
titel = 'Migration'
txt1 = 'Automatic migration of .abapgit.xml removed'
txt2 = 'Remove all repos and install latest abapGit version'.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD rebuild_local_checksums_161112.
DATA: lt_repos TYPE zif_abapgit_definitions=>ty_repo_ref_tt,
lv_repo_list TYPE string,
lv_index TYPE i.
FIELD-SYMBOLS: <lo_repo> LIKE LINE OF lt_repos.
lt_repos = zcl_abapgit_repo_srv=>get_instance( )->list( ).
LOOP AT lt_repos ASSIGNING <lo_repo>.
lv_index = sy-tabix.
IF <lo_repo>->is_offline( ) = abap_true. " Skip local repos
DELETE lt_repos INDEX lv_index.
CONTINUE.
ENDIF.
" Ignore empty repos or repos with file checksums
IF lines( <lo_repo>->get_local_checksums( ) ) = 0
OR lines( <lo_repo>->get_local_checksums_per_file( ) ) > 0.
DELETE lt_repos INDEX lv_index.
CONTINUE.
ENDIF.
lv_repo_list = lv_repo_list && `, ` && <lo_repo>->get_name( ).
ENDLOOP.
IF lines( lt_repos ) = 0.
RETURN. " All OK
ENDIF.
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
titel = 'Migration'
txt1 = 'Automatic migration of local checksums removed'
txt2 = 'Remove all repos and install latest abapGit version'.
ENDMETHOD.
METHOD run.
" Migrate STDTEXT to TABLE
zcl_abapgit_persist_migrate=>run( ).
" Rebuild local file checksums
rebuild_local_checksums_161112( ).
" local .abapgit.xml state, issue #630
local_dot_abapgit( ).
ENDMETHOD. " run.
ENDCLASS.
CLASS ZCL_ABAPGIT_MERGE IMPLEMENTATION.
METHOD all_files.
APPEND LINES OF ms_merge-stree TO rt_files.
APPEND LINES OF ms_merge-ttree TO rt_files.
APPEND LINES OF ms_merge-ctree TO rt_files.
SORT rt_files BY path DESCENDING name ASCENDING.
DELETE ADJACENT DUPLICATES FROM rt_files COMPARING path name.
ENDMETHOD.
METHOD calculate_result.
DEFINE _from_source.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-blob
sha1 = <ls_source>-sha1.
ASSERT sy-subrc = 0.
ms_merge-stage->add( iv_path = <ls_file>-path
iv_filename = <ls_file>-name
iv_data = <ls_object>-data ).
END-OF-DEFINITION.
DATA: lt_files TYPE zif_abapgit_definitions=>ty_expanded_tt,
lv_found_source TYPE abap_bool,
lv_found_target TYPE abap_bool,
lv_found_common TYPE abap_bool.
FIELD-SYMBOLS: <ls_source> LIKE LINE OF lt_files,
<ls_target> LIKE LINE OF lt_files,
<ls_common> LIKE LINE OF lt_files,
<ls_file> LIKE LINE OF lt_files,
<ls_result> LIKE LINE OF ms_merge-result,
<ls_object> LIKE LINE OF mt_objects,
<ls_conflict> LIKE LINE OF mt_conflicts.
lt_files = all_files( ).
CREATE OBJECT ms_merge-stage
EXPORTING
iv_merge_source = ms_merge-source-sha1.
LOOP AT lt_files ASSIGNING <ls_file>.
UNASSIGN <ls_source>.
UNASSIGN <ls_target>.
UNASSIGN <ls_common>.
READ TABLE ms_merge-stree ASSIGNING <ls_source>
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
READ TABLE ms_merge-ttree ASSIGNING <ls_target>
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
READ TABLE ms_merge-ctree ASSIGNING <ls_common>
WITH KEY path = <ls_file>-path name = <ls_file>-name. "#EC CI_SUBRC
lv_found_source = boolc( <ls_source> IS ASSIGNED ).
lv_found_target = boolc( <ls_target> IS ASSIGNED ).
lv_found_common = boolc( <ls_common> IS ASSIGNED ).
IF lv_found_source = abap_false
AND lv_found_target = abap_false.
CONTINUE.
ELSEIF lv_found_source = abap_false
AND lv_found_common = abap_true
AND <ls_target>-sha1 = <ls_common>-sha1.
ms_merge-stage->rm( iv_path = <ls_file>-path
iv_filename = <ls_file>-name ).
CONTINUE.
ELSEIF lv_found_target = abap_false
AND lv_found_common = abap_true
AND <ls_source>-sha1 = <ls_common>-sha1.
CONTINUE.
ENDIF.
APPEND INITIAL LINE TO ms_merge-result ASSIGNING <ls_result>.
<ls_result>-path = <ls_file>-path.
<ls_result>-name = <ls_file>-name.
IF lv_found_target = abap_false.
_from_source.
<ls_result>-sha1 = <ls_source>-sha1.
CONTINUE.
ELSEIF lv_found_source = abap_false.
<ls_result>-sha1 = <ls_target>-sha1.
ELSEIF lv_found_common = abap_false
AND <ls_target>-sha1 = <ls_source>-sha1.
<ls_result>-sha1 = <ls_source>-sha1.
ELSEIF lv_found_common = abap_false
AND <ls_target>-sha1 <> <ls_source>-sha1.
INSERT INITIAL LINE INTO TABLE mt_conflicts ASSIGNING <ls_conflict>.
<ls_conflict>-path = <ls_file>-path.
<ls_conflict>-filename = <ls_file>-name.
<ls_conflict>-source_sha1 = <ls_source>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-blob
sha1 = <ls_source>-sha1.
<ls_conflict>-source_data = <ls_object>-data.
<ls_conflict>-target_sha1 = <ls_target>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-blob
sha1 = <ls_target>-sha1.
<ls_conflict>-target_data = <ls_object>-data.
ms_merge-conflict = |{ <ls_file>-name } merge conflict|.
CONTINUE.
ENDIF.
IF lv_found_source = abap_false
OR lv_found_target = abap_false
OR lv_found_common = abap_false.
ms_merge-conflict = |{ <ls_file>-name } merge conflict, not found anywhere|.
CONTINUE.
ENDIF.
IF <ls_target>-sha1 = <ls_source>-sha1.
<ls_result>-sha1 = <ls_source>-sha1.
ELSEIF <ls_target>-sha1 = <ls_common>-sha1.
_from_source.
<ls_result>-sha1 = <ls_source>-sha1.
ELSEIF <ls_source>-sha1 = <ls_common>-sha1.
<ls_result>-sha1 = <ls_target>-sha1.
ELSE.
INSERT INITIAL LINE INTO TABLE mt_conflicts ASSIGNING <ls_conflict>.
<ls_conflict>-path = <ls_file>-path.
<ls_conflict>-filename = <ls_file>-name.
<ls_conflict>-source_sha1 = <ls_source>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-blob
sha1 = <ls_source>-sha1.
<ls_conflict>-source_data = <ls_object>-data.
<ls_conflict>-target_sha1 = <ls_target>-sha1.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-blob
sha1 = <ls_target>-sha1.
<ls_conflict>-target_data = <ls_object>-data.
ms_merge-conflict = |{ <ls_file>-name } merge conflict, changed in source and target branch|.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD constructor.
IF iv_source_branch EQ io_repo->get_branch_name( ).
zcx_abapgit_exception=>raise( 'source = target' ).
ENDIF.
mo_repo = io_repo.
mv_source_branch = iv_source_branch.
ENDMETHOD.
METHOD fetch_git.
DATA: lo_branch_list TYPE REF TO zcl_abapgit_git_branch_list,
lt_upload TYPE zif_abapgit_definitions=>ty_git_branch_list_tt.
lo_branch_list = zcl_abapgit_git_transport=>branches( ms_merge-repo->get_url( ) ).
ms_merge-source = lo_branch_list->find_by_name(
zcl_abapgit_git_branch_list=>complete_heads_branch_name( mv_source_branch ) ).
ms_merge-target = lo_branch_list->find_by_name(
zcl_abapgit_git_branch_list=>complete_heads_branch_name( mo_repo->get_branch_name( ) ) ).
APPEND ms_merge-source TO lt_upload.
APPEND ms_merge-target TO lt_upload.
zcl_abapgit_git_transport=>upload_pack(
EXPORTING
iv_url = ms_merge-repo->get_url( )
iv_branch_name = ms_merge-repo->get_branch_name( )
iv_deepen = abap_false
it_branches = lt_upload
IMPORTING
et_objects = rt_objects ).
ENDMETHOD.
METHOD find_ancestors.
DEFINE _visit.
IF NOT &1 IS INITIAL.
READ TABLE lt_visit FROM &1 TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
APPEND &1 TO lt_visit.
ENDIF.
ENDIF.
END-OF-DEFINITION.
DATA: ls_commit TYPE zcl_abapgit_git_pack=>ty_commit,
lt_visit TYPE STANDARD TABLE OF zif_abapgit_definitions=>ty_sha1,
lv_commit LIKE LINE OF lt_visit.
FIELD-SYMBOLS: <ls_ancestor> LIKE LINE OF rt_ancestors,
<ls_object> LIKE LINE OF mt_objects.
APPEND iv_commit TO lt_visit.
LOOP AT lt_visit INTO lv_commit.
READ TABLE mt_objects ASSIGNING <ls_object>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-commit
sha1 = lv_commit.
ASSERT sy-subrc = 0.
ls_commit = zcl_abapgit_git_pack=>decode_commit( <ls_object>-data ).
_visit ls_commit-parent.
_visit ls_commit-parent2.
APPEND INITIAL LINE TO rt_ancestors ASSIGNING <ls_ancestor>.
<ls_ancestor>-commit = lv_commit.
<ls_ancestor>-tree = ls_commit-tree.
<ls_ancestor>-body = ls_commit-body.
<ls_ancestor>-time = ls_commit-author.
"Strip Author entry of all but the time component
REPLACE ALL OCCURRENCES OF REGEX '[a-zA-Z<>@.-]*' IN <ls_ancestor>-time WITH ''.
CONDENSE <ls_ancestor>-time.
ENDLOOP.
SORT rt_ancestors BY time DESCENDING.
ENDMETHOD.
METHOD find_first_common.
FIELD-SYMBOLS: <ls_list1> LIKE LINE OF it_list1,
<ls_list2> LIKE LINE OF it_list2.
LOOP AT it_list1 ASSIGNING <ls_list1>.
LOOP AT it_list2 ASSIGNING <ls_list2>.
IF <ls_list1>-tree = <ls_list2>-tree.
rs_common = <ls_list1>.
RETURN.
ENDIF.
ENDLOOP.
ENDLOOP.
zcx_abapgit_exception=>raise( 'error finding common ancestor' ).
ENDMETHOD.
METHOD get_conflicts.
rt_conflicts = mt_conflicts.
ENDMETHOD.
METHOD get_result.
rs_merge = ms_merge.
ENDMETHOD.
METHOD get_source_branch.
rv_source_branch = mv_source_branch.
ENDMETHOD.
METHOD has_conflicts.
IF lines( mt_conflicts ) > 0.
rv_conflicts_exists = abap_true.
ELSE.
rv_conflicts_exists = abap_false.
ENDIF.
ENDMETHOD.
METHOD resolve_conflict.
FIELD-SYMBOLS: <ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict,
<ls_result> LIKE LINE OF ms_merge-result.
IF is_conflict-result_sha1 IS NOT INITIAL
AND is_conflict-result_data IS NOT INITIAL.
READ TABLE mt_conflicts ASSIGNING <ls_conflict> WITH KEY path = is_conflict-path
filename = is_conflict-filename.
IF sy-subrc EQ 0.
READ TABLE ms_merge-result ASSIGNING <ls_result> WITH KEY path = is_conflict-path
name = is_conflict-filename.
IF sy-subrc EQ 0.
<ls_result>-sha1 = is_conflict-result_sha1.
ms_merge-stage->add( iv_path = <ls_conflict>-path
iv_filename = <ls_conflict>-filename
iv_data = is_conflict-result_data ).
DELETE mt_conflicts WHERE path EQ is_conflict-path
AND filename EQ is_conflict-filename.
ENDIF.
READ TABLE ms_merge-result ASSIGNING <ls_result> WITH KEY sha1 = space.
IF sy-subrc EQ 0.
ms_merge-conflict = |{ <ls_result>-name } merge conflict, changed in source and target branch|.
ELSE.
CLEAR ms_merge-conflict.
ENDIF.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD run.
DATA: lt_asource TYPE ty_ancestor_tt,
lt_atarget TYPE ty_ancestor_tt.
CLEAR: ms_merge, mt_objects, mt_conflicts.
ms_merge-repo = mo_repo.
mt_objects = fetch_git( ).
lt_asource = find_ancestors( ms_merge-source-sha1 ).
lt_atarget = find_ancestors( ms_merge-target-sha1 ).
ms_merge-common = find_first_common( it_list1 = lt_asource
it_list2 = lt_atarget ).
ms_merge-stree = zcl_abapgit_git_porcelain=>full_tree(
it_objects = mt_objects
iv_branch = ms_merge-source-sha1 ).
ms_merge-ttree = zcl_abapgit_git_porcelain=>full_tree(
it_objects = mt_objects
iv_branch = ms_merge-target-sha1 ).
ms_merge-ctree = zcl_abapgit_git_porcelain=>full_tree(
it_objects = mt_objects
iv_branch = ms_merge-common-commit ).
calculate_result( ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_injector IMPLEMENTATION.
METHOD set_tadir.
zcl_abapgit_factory=>gi_tadir = ii_tadir.
ENDMETHOD.
METHOD set_sap_package.
DATA: ls_sap_package TYPE zcl_abapgit_factory=>ty_sap_package.
FIELD-SYMBOLS: <ls_sap_package> TYPE zcl_abapgit_factory=>ty_sap_package.
READ TABLE zcl_abapgit_factory=>gt_sap_package
ASSIGNING <ls_sap_package>
WITH TABLE KEY package = iv_package.
IF sy-subrc <> 0.
ls_sap_package-package = iv_package.
INSERT ls_sap_package
INTO TABLE zcl_abapgit_factory=>gt_sap_package
ASSIGNING <ls_sap_package>.
ENDIF.
<ls_sap_package>-instance = ii_sap_package.
ENDMETHOD.
METHOD set_code_inspector.
DATA: ls_code_inspector LIKE LINE OF zcl_abapgit_factory=>gt_code_inspector.
FIELD-SYMBOLS: <ls_code_inspector> LIKE LINE OF zcl_abapgit_factory=>gt_code_inspector.
READ TABLE zcl_abapgit_factory=>gt_code_inspector
ASSIGNING <ls_code_inspector>
WITH TABLE KEY package = iv_package
check_variant_name = iv_check_variant_name.
IF sy-subrc <> 0.
ls_code_inspector-package = iv_package.
ls_code_inspector-check_variant_name = iv_check_variant_name.
INSERT ls_code_inspector
INTO TABLE zcl_abapgit_factory=>gt_code_inspector
ASSIGNING <ls_code_inspector>.
ENDIF.
<ls_code_inspector>-instance = ii_code_inspector.
ENDMETHOD.
METHOD set_syntax_check.
DATA: ls_syntax_check LIKE LINE OF zcl_abapgit_factory=>gt_syntax_check.
FIELD-SYMBOLS: <ls_syntax_check> LIKE LINE OF zcl_abapgit_factory=>gt_syntax_check.
READ TABLE zcl_abapgit_factory=>gt_syntax_check
ASSIGNING <ls_syntax_check>
WITH TABLE KEY package = iv_package.
IF sy-subrc <> 0.
ls_syntax_check-package = iv_package.
INSERT ls_syntax_check
INTO TABLE zcl_abapgit_factory=>gt_syntax_check
ASSIGNING <ls_syntax_check>.
ENDIF.
<ls_syntax_check>-instance = ii_syntax_check.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_HTTP_CLIENT IMPLEMENTATION.
METHOD check_http_200.
DATA: lv_code TYPE i,
lv_text TYPE string.
mi_client->response->get_status(
IMPORTING
code = lv_code ).
CASE lv_code.
WHEN 200.
RETURN.
WHEN 302.
zcx_abapgit_exception=>raise( 'HTTP redirect, check URL' ).
WHEN 401.
zcx_abapgit_exception=>raise( 'HTTP 401, unauthorized' ).
WHEN 403.
zcx_abapgit_exception=>raise( 'HTTP 403, forbidden' ).
WHEN 404.
zcx_abapgit_exception=>raise( 'HTTP 404, not found' ).
WHEN 415.
zcx_abapgit_exception=>raise( 'HTTP 415, unsupported media type' ).
WHEN OTHERS.
lv_text = mi_client->response->get_cdata( ).
zcx_abapgit_exception=>raise( |HTTP error code: { lv_code }, { lv_text }| ).
ENDCASE.
ENDMETHOD. "http_200
METHOD close.
mi_client->close( ).
ENDMETHOD.
METHOD constructor.
mi_client = ii_client.
ENDMETHOD.
METHOD get_cdata.
rv_value = mi_client->response->get_cdata( ).
ENDMETHOD.
METHOD send_receive.
DATA: lv_text TYPE string,
lv_code TYPE i,
lv_message TYPE string.
mi_client->send( ).
mi_client->receive(
EXCEPTIONS
http_communication_failure = 1
http_invalid_state = 2
http_processing_failed = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
" in case of HTTP_COMMUNICATION_FAILURE
" make sure:
" a) SSL is setup properly in STRUST
" b) no firewalls
" check trace file in transaction SMICM
mi_client->get_last_error(
IMPORTING
code = lv_code
message = lv_message ).
lv_text = |HTTP error { lv_code } occured: { lv_message }|.
zcx_abapgit_exception=>raise( lv_text ).
ENDIF.
ENDMETHOD. "send_receive
METHOD send_receive_close.
mi_client->request->set_data( iv_data ).
send_receive( ).
check_http_200( ).
rv_data = mi_client->response->get_data( ).
mi_client->close( ).
ENDMETHOD.
METHOD set_digest.
mo_digest = io_digest.
ENDMETHOD.
METHOD set_headers.
DATA: lv_value TYPE string.
mi_client->request->set_header_field(
name = '~request_method'
value = 'POST' ).
lv_value = zcl_abapgit_url=>path_name( iv_url ) &&
'/git-' &&
iv_service &&
'-pack'.
mi_client->request->set_header_field(
name = '~request_uri'
value = lv_value ).
lv_value = 'application/x-git-'
&& iv_service && '-pack-request'. "#EC NOTEXT
mi_client->request->set_header_field(
name = 'Content-Type'
value = lv_value ). "#EC NOTEXT
lv_value = 'application/x-git-'
&& iv_service && '-pack-result'. "#EC NOTEXT
mi_client->request->set_header_field(
name = 'Accept'
value = lv_value ). "#EC NOTEXT
IF mo_digest IS BOUND.
mo_digest->run( mi_client ).
ENDIF.
ENDMETHOD. "set_headers
ENDCLASS.
CLASS ZCL_ABAPGIT_FOLDER_LOGIC IMPLEMENTATION.
METHOD get_instance.
CREATE OBJECT ro_instance.
ENDMETHOD.
METHOD get_parent.
DATA: st_parent LIKE LINE OF mt_parent.
"Determine Parent Package
READ TABLE mt_parent INTO st_parent
WITH TABLE KEY devclass = iv_package.
IF sy-subrc <> 0.
r_parent = zcl_abapgit_factory=>get_sap_package( iv_package )->read_parent( ).
st_parent-devclass = iv_package.
st_parent-parentcl = r_parent.
INSERT st_parent INTO TABLE mt_parent.
ELSE.
r_parent = st_parent-parentcl.
ENDIF.
ENDMETHOD.
METHOD package_to_path.
DATA: lv_len TYPE i,
lv_path TYPE string,
lv_message TYPE string,
lv_parentcl TYPE tdevc-parentcl,
lv_folder_logic TYPE string.
IF iv_top = iv_package.
rv_path = io_dot->get_starting_folder( ).
ELSE.
lv_parentcl = get_parent( iv_package ).
IF lv_parentcl IS INITIAL.
zcx_abapgit_exception=>raise( |error, expected parent package, { iv_package }| ).
ELSE.
lv_folder_logic = io_dot->get_folder_logic( ).
CASE lv_folder_logic.
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-full.
lv_len = 0.
IF iv_package(1) = '$'.
lv_len = 1.
ENDIF.
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-prefix.
lv_len = strlen( lv_parentcl ).
IF iv_package(lv_len) <> lv_parentcl.
lv_message = 'PREFIX: Unexpected package naming (' && iv_package && ')'
&& 'you might switch to FULL folder logic' ##no_text.
zcx_abapgit_exception=>raise( lv_message ).
ENDIF.
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Invalid folder logic: { lv_folder_logic }| ).
ENDCASE.
lv_path = iv_package+lv_len.
IF strlen( lv_path ) = 0.
zcx_abapgit_exception=>raise( |Folder logic: length = 0, parent: {
lv_parentcl }, child: { iv_package }| ).
ENDIF.
IF lv_path(1) = '_'.
lv_path = lv_path+1.
ENDIF.
IF strlen( lv_path ) = 0.
zcx_abapgit_exception=>raise( |Folder logic: length = 0, parent: {
lv_parentcl }, child: { iv_package }| ).
ENDIF.
TRANSLATE lv_path USING '/#'.
TRANSLATE lv_path TO LOWER CASE.
CONCATENATE lv_path '/' INTO lv_path.
rv_path = package_to_path( iv_top = iv_top
io_dot = io_dot
iv_package = lv_parentcl ).
CONCATENATE rv_path lv_path INTO rv_path.
ENDIF.
ENDIF.
ENDMETHOD. "class_to_path
METHOD path_to_package.
DATA: lv_length TYPE i,
lv_parent TYPE devclass,
lv_new TYPE string,
lv_path TYPE string,
lv_top TYPE devclass.
lv_top = iv_top.
lv_length = strlen( io_dot->get_starting_folder( ) ).
IF lv_length > strlen( iv_path ).
RETURN.
ENDIF.
lv_path = iv_path+lv_length.
lv_parent = lv_top.
rv_package = lv_top.
WHILE lv_path CA '/'.
SPLIT lv_path AT '/' INTO lv_new lv_path.
CASE io_dot->get_folder_logic( ).
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-full.
rv_package = lv_new.
TRANSLATE rv_package USING '#/'.
IF iv_top(1) = '$'.
CONCATENATE '$' rv_package INTO rv_package.
ENDIF.
WHEN zif_abapgit_dot_abapgit=>c_folder_logic-prefix.
CONCATENATE rv_package '_' lv_new INTO rv_package.
WHEN OTHERS.
ASSERT 0 = 1.
ENDCASE.
TRANSLATE rv_package TO UPPER CASE.
IF zcl_abapgit_factory=>get_sap_package( rv_package )->exists( ) = abap_false AND
iv_create_if_not_exists = abap_true.
zcl_abapgit_factory=>get_sap_package( lv_parent )->create_child( rv_package ).
ENDIF.
lv_parent = rv_package.
ENDWHILE.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_FILE_STATUS IMPLEMENTATION.
METHOD build_existing.
DATA: ls_file_sig LIKE LINE OF it_state.
" Item
rs_result-obj_type = is_local-item-obj_type.
rs_result-obj_name = is_local-item-obj_name.
rs_result-package = is_local-item-devclass.
" File
rs_result-path = is_local-file-path.
rs_result-filename = is_local-file-filename.
IF is_local-file-sha1 = is_remote-sha1.
rs_result-match = abap_true.
RETURN.
ENDIF.
" Match against current state
READ TABLE it_state INTO ls_file_sig
WITH KEY path = is_local-file-path
filename = is_local-file-filename
BINARY SEARCH.
IF sy-subrc = 0.
IF ls_file_sig-sha1 <> is_local-file-sha1.
rs_result-lstate = zif_abapgit_definitions=>c_state-modified.
ENDIF.
IF ls_file_sig-sha1 <> is_remote-sha1.
rs_result-rstate = zif_abapgit_definitions=>c_state-modified.
ENDIF.
rs_result-match = boolc( rs_result-lstate IS INITIAL
AND rs_result-rstate IS INITIAL ).
ELSE.
" This is a strange situation. As both local and remote exist
" the state should also be present. Maybe this is a first run of the code.
" In this case just compare hashes directly and mark both changed
" the user will presumably decide what to do after checking the actual diff
rs_result-match = boolc( is_local-file-sha1 = is_remote-sha1 ).
IF rs_result-match = abap_false.
rs_result-lstate = zif_abapgit_definitions=>c_state-modified.
rs_result-rstate = zif_abapgit_definitions=>c_state-modified.
ENDIF.
ENDIF.
ENDMETHOD. "build_existing
METHOD build_new_local.
" Item
rs_result-obj_type = is_local-item-obj_type.
rs_result-obj_name = is_local-item-obj_name.
rs_result-package = is_local-item-devclass.
" File
rs_result-path = is_local-file-path.
rs_result-filename = is_local-file-filename.
" Match
rs_result-match = abap_false.
rs_result-lstate = zif_abapgit_definitions=>c_state-added.
ENDMETHOD. "build_new_local
METHOD build_new_remote.
DATA: ls_item LIKE LINE OF it_items,
ls_file_sig LIKE LINE OF it_state.
" Common and default part
rs_result-path = is_remote-path.
rs_result-filename = is_remote-filename.
rs_result-match = abap_false.
rs_result-rstate = zif_abapgit_definitions=>c_state-added.
identify_object( EXPORTING iv_filename = is_remote-filename
iv_path = is_remote-path
iv_devclass = iv_devclass
io_dot = io_dot
IMPORTING es_item = ls_item ).
" Check if in item index + get package
READ TABLE it_items INTO ls_item
WITH KEY obj_type = ls_item-obj_type obj_name = ls_item-obj_name
BINARY SEARCH.
IF sy-subrc = 0.
" Completely new (xml, abap) and new file in an existing object
rs_result-obj_type = ls_item-obj_type.
rs_result-obj_name = ls_item-obj_name.
rs_result-package = ls_item-devclass.
READ TABLE it_state INTO ls_file_sig
WITH KEY path = is_remote-path filename = is_remote-filename
BINARY SEARCH.
" Existing file but from another package
" was not added during local file proc as was not in tadir for repo package
IF sy-subrc = 0.
IF ls_file_sig-sha1 = is_remote-sha1.
rs_result-match = abap_true.
CLEAR rs_result-rstate.
ELSE.
rs_result-rstate = zif_abapgit_definitions=>c_state-modified.
ENDIF.
" Item is in state and in cache but with no package - it was deleted
" OR devclass is the same as repo package (see #532)
IF ls_item-devclass IS INITIAL OR ls_item-devclass = iv_devclass.
rs_result-match = abap_false.
rs_result-lstate = zif_abapgit_definitions=>c_state-deleted.
ENDIF.
ENDIF.
ELSE. " Completely unknown file, probably non-abapgit
ASSERT 1 = 1. " No action, just follow defaults
ENDIF.
ENDMETHOD. "build_new_remote
METHOD calculate_status.
DATA: lt_remote LIKE it_remote,
lt_items TYPE zif_abapgit_definitions=>ty_items_tt,
ls_item LIKE LINE OF lt_items,
lv_is_xml TYPE abap_bool,
lv_sub_fetched TYPE abap_bool,
lt_sub_packages TYPE zif_abapgit_sap_package=>ty_devclass_tt,
lt_items_idx TYPE zif_abapgit_definitions=>ty_items_ts,
lt_state_idx TYPE zif_abapgit_definitions=>ty_file_signatures_ts. " Sorted by path+filename
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF it_remote,
<ls_result> LIKE LINE OF rt_results,
<ls_local> LIKE LINE OF it_local.
lt_state_idx = it_cur_state. " Force sort it
lt_remote = it_remote.
SORT lt_remote BY path filename.
" Process local files and new local files
LOOP AT it_local ASSIGNING <ls_local>.
APPEND INITIAL LINE TO rt_results ASSIGNING <ls_result>.
IF <ls_local>-item IS NOT INITIAL.
APPEND <ls_local>-item TO lt_items. " Collect for item index
ENDIF.
READ TABLE lt_remote ASSIGNING <ls_remote>
WITH KEY path = <ls_local>-file-path filename = <ls_local>-file-filename
BINARY SEARCH.
IF sy-subrc = 0. " Exist local and remote
<ls_result> = build_existing(
is_local = <ls_local>
is_remote = <ls_remote>
it_state = lt_state_idx ).
ASSERT <ls_remote>-sha1 IS NOT INITIAL.
CLEAR <ls_remote>-sha1. " Mark as processed
ELSE. " Only L exists
<ls_result> = build_new_local( <ls_local> ).
ENDIF.
ENDLOOP.
" Complete item index for unmarked remote files
LOOP AT lt_remote ASSIGNING <ls_remote> WHERE sha1 IS NOT INITIAL.
identify_object( EXPORTING iv_filename = <ls_remote>-filename
iv_path = <ls_remote>-path
io_dot = io_dot
iv_devclass = iv_devclass
IMPORTING es_item = ls_item
ev_is_xml = lv_is_xml ).
CHECK lv_is_xml = abap_true. " Skip all but obj definitions
ls_item-devclass = zcl_abapgit_factory=>get_tadir( )->get_object_package(
iv_object = ls_item-obj_type
iv_obj_name = ls_item-obj_name ).
IF NOT ls_item-devclass IS INITIAL AND iv_devclass <> ls_item-devclass.
IF lv_sub_fetched = abap_false.
lt_sub_packages = zcl_abapgit_factory=>get_sap_package( iv_devclass )->list_subpackages( ).
lv_sub_fetched = abap_true.
SORT lt_sub_packages BY table_line. "Optimize Read Access
ENDIF.
READ TABLE lt_sub_packages TRANSPORTING NO FIELDS
WITH KEY table_line = ls_item-devclass
BINARY SEARCH.
IF sy-subrc <> 0.
CLEAR ls_item-devclass.
ENDIF.
ENDIF.
APPEND ls_item TO lt_items.
ENDLOOP.
SORT lt_items. " Default key - type, name, pkg
DELETE ADJACENT DUPLICATES FROM lt_items.
lt_items_idx = lt_items. " Self protection + UNIQUE records assertion
" Process new remote files (marked above with empty SHA1)
LOOP AT lt_remote ASSIGNING <ls_remote> WHERE sha1 IS NOT INITIAL.
APPEND INITIAL LINE TO rt_results ASSIGNING <ls_result>.
<ls_result> = build_new_remote( iv_devclass = iv_devclass
io_dot = io_dot
is_remote = <ls_remote>
it_items = lt_items_idx
it_state = lt_state_idx ).
ENDLOOP.
SORT rt_results BY
obj_type ASCENDING
obj_name ASCENDING
filename ASCENDING.
ENDMETHOD. "calculate_status.
METHOD identify_object.
DATA: lv_name TYPE tadir-obj_name,
lv_type TYPE string,
lv_ext TYPE string.
" Guess object type and name
SPLIT to_upper( iv_filename ) AT '.' INTO lv_name lv_type lv_ext.
" Handle namespaces
REPLACE ALL OCCURRENCES OF '#' IN lv_name WITH '/'.
REPLACE ALL OCCURRENCES OF '#' IN lv_type WITH '/'.
REPLACE ALL OCCURRENCES OF '#' IN lv_ext WITH '/'.
" Try to get a unique package name for DEVC by using the path
IF lv_type = 'DEVC'.
ASSERT lv_name = 'PACKAGE'.
lv_name = zcl_abapgit_folder_logic=>get_instance( )->path_to_package(
iv_top = iv_devclass
io_dot = io_dot
iv_create_if_not_exists = abap_false
iv_path = iv_path ).
ENDIF.
CLEAR es_item.
es_item-obj_type = lv_type.
es_item-obj_name = lv_name.
ev_is_xml = boolc( lv_ext = 'XML' AND strlen( lv_type ) = 4 ).
ENDMETHOD. "identify_object.
METHOD run_checks.
DATA: lv_path TYPE string,
ls_item TYPE zif_abapgit_definitions=>ty_item,
ls_file TYPE zif_abapgit_definitions=>ty_file_signature,
lt_res_sort LIKE it_results,
lt_item_idx LIKE it_results.
DATA: lo_folder_logic TYPE REF TO zcl_abapgit_folder_logic.
FIELD-SYMBOLS: <ls_res1> LIKE LINE OF it_results,
<ls_res2> LIKE LINE OF it_results.
IF io_log IS INITIAL.
RETURN.
ENDIF.
" Collect object indexe
lt_res_sort = it_results.
SORT lt_res_sort BY obj_type ASCENDING obj_name ASCENDING.
LOOP AT it_results ASSIGNING <ls_res1> WHERE NOT obj_type IS INITIAL.
IF NOT ( <ls_res1>-obj_type = ls_item-obj_type
AND <ls_res1>-obj_name = ls_item-obj_name ).
APPEND INITIAL LINE TO lt_item_idx ASSIGNING <ls_res2>.
<ls_res2>-obj_type = <ls_res1>-obj_type.
<ls_res2>-obj_name = <ls_res1>-obj_name.
<ls_res2>-path = <ls_res1>-path.
MOVE-CORRESPONDING <ls_res1> TO ls_item.
ENDIF.
ENDLOOP.
" Check files for one object is in the same folder
LOOP AT it_results ASSIGNING <ls_res1> WHERE NOT obj_type IS INITIAL AND obj_type <> 'DEVC'.
READ TABLE lt_item_idx ASSIGNING <ls_res2>
WITH KEY obj_type = <ls_res1>-obj_type obj_name = <ls_res1>-obj_name
BINARY SEARCH. " Sorted above
IF sy-subrc <> 0 OR <ls_res1>-path <> <ls_res2>-path. " All paths are same
io_log->add( iv_msg = |Files for object { <ls_res1>-obj_type } {
<ls_res1>-obj_name } are not placed in the same folder|
iv_type = 'W'
iv_rc = '1' ) ##no_text.
ENDIF.
ENDLOOP.
" Check that objects are created in package corresponding to folder
lo_folder_logic = zcl_abapgit_folder_logic=>get_instance( ).
LOOP AT it_results ASSIGNING <ls_res1>
WHERE NOT package IS INITIAL AND NOT path IS INITIAL.
lv_path = lo_folder_logic->package_to_path(
iv_top = iv_top
io_dot = io_dot
iv_package = <ls_res1>-package ).
IF lv_path <> <ls_res1>-path.
io_log->add( iv_msg = |Package and path does not match for object, {
<ls_res1>-obj_type } { <ls_res1>-obj_name }|
iv_type = 'W'
iv_rc = '2' ) ##no_text.
ENDIF.
ENDLOOP.
" Check for multiple files with same filename
SORT lt_res_sort BY filename ASCENDING.
LOOP AT lt_res_sort ASSIGNING <ls_res1> WHERE obj_type <> 'DEVC'.
IF <ls_res1>-filename IS NOT INITIAL AND <ls_res1>-filename = ls_file-filename.
io_log->add( iv_msg = |Multiple files with same filename, { <ls_res1>-filename }|
iv_type = 'W'
iv_rc = '3' ) ##no_text.
ENDIF.
IF <ls_res1>-filename IS INITIAL.
io_log->add( iv_msg = |Filename is empty for object { <ls_res1>-obj_type } { <ls_res1>-obj_name }|
iv_type = 'W'
iv_rc = '4' ) ##no_text.
ENDIF.
MOVE-CORRESPONDING <ls_res1> TO ls_file.
ENDLOOP.
ENDMETHOD. "check
METHOD status.
DATA: lv_index LIKE sy-tabix,
lo_dot_abapgit TYPE REF TO zcl_abapgit_dot_abapgit.
FIELD-SYMBOLS <ls_result> LIKE LINE OF rt_results.
rt_results = calculate_status(
iv_devclass = io_repo->get_package( )
io_dot = io_repo->get_dot_abapgit( )
it_local = io_repo->get_files_local( io_log = io_log )
it_remote = io_repo->get_files_remote( )
it_cur_state = io_repo->get_local_checksums_per_file( ) ).
lo_dot_abapgit = io_repo->get_dot_abapgit( ).
" Remove ignored files, fix .abapgit
LOOP AT rt_results ASSIGNING <ls_result>.
lv_index = sy-tabix.
IF lo_dot_abapgit->is_ignored(
iv_path = <ls_result>-path
iv_filename = <ls_result>-filename ) = abap_true.
DELETE rt_results INDEX lv_index.
CONTINUE.
ENDIF.
ENDLOOP.
run_checks(
io_log = io_log
it_results = rt_results
io_dot = lo_dot_abapgit
iv_top = io_repo->get_package( ) ).
ENDMETHOD. "status
ENDCLASS.
CLASS zcl_abapgit_factory IMPLEMENTATION.
METHOD get_tadir.
IF gi_tadir IS INITIAL.
CREATE OBJECT gi_tadir TYPE zcl_abapgit_tadir.
ENDIF.
ri_tadir = gi_tadir.
ENDMETHOD.
METHOD get_sap_package.
DATA: ls_sap_package TYPE ty_sap_package.
FIELD-SYMBOLS: <ls_sap_package> TYPE ty_sap_package.
READ TABLE gt_sap_package ASSIGNING <ls_sap_package>
WITH TABLE KEY package = iv_package.
IF sy-subrc <> 0.
ls_sap_package-package = iv_package.
CREATE OBJECT ls_sap_package-instance TYPE zcl_abapgit_sap_package
EXPORTING
iv_package = iv_package.
INSERT ls_sap_package
INTO TABLE gt_sap_package
ASSIGNING <ls_sap_package>.
ENDIF.
ri_sap_package = <ls_sap_package>-instance.
ENDMETHOD.
METHOD get_code_inspector.
DATA: ls_code_inspector LIKE LINE OF gt_code_inspector.
FIELD-SYMBOLS: <ls_code_inspector> TYPE zcl_abapgit_factory=>ty_code_inspector.
READ TABLE gt_code_inspector ASSIGNING <ls_code_inspector>
WITH TABLE KEY package = iv_package
check_variant_name = iv_check_variant_name.
IF sy-subrc <> 0.
ls_code_inspector-package = iv_package.
ls_code_inspector-check_variant_name = iv_check_variant_name.
CREATE OBJECT ls_code_inspector-instance TYPE zcl_abapgit_code_inspector
EXPORTING
iv_package = iv_package
iv_check_variant_name = iv_check_variant_name.
INSERT ls_code_inspector
INTO TABLE gt_code_inspector
ASSIGNING <ls_code_inspector>.
ENDIF.
ri_code_inspector = <ls_code_inspector>-instance.
ENDMETHOD.
METHOD get_syntax_check.
DATA: ls_syntax_check LIKE LINE OF gt_syntax_check.
FIELD-SYMBOLS: <ls_syntax_check> TYPE zcl_abapgit_factory=>ty_syntax_check.
READ TABLE gt_syntax_check ASSIGNING <ls_syntax_check>
WITH TABLE KEY package = iv_package.
IF sy-subrc <> 0.
ls_syntax_check-package = iv_package.
CREATE OBJECT ls_syntax_check-instance TYPE zcl_abapgit_syntax_check
EXPORTING
iv_package = iv_package.
INSERT ls_syntax_check
INTO TABLE gt_syntax_check
ASSIGNING <ls_syntax_check>.
ENDIF.
ri_syntax_check = <ls_syntax_check>-instance.
ENDMETHOD.
METHOD get_branch_overview.
CREATE OBJECT ri_branch_overview
TYPE zcl_abapgit_branch_overview
EXPORTING
io_repo = io_repo.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_exit IMPLEMENTATION.
METHOD get_instance.
IF gi_exit IS INITIAL.
TRY.
CREATE OBJECT gi_exit TYPE ('ZCL_ABAPGIT_USER_EXIT').
CATCH cx_sy_create_object_error.
ENDTRY.
ENDIF.
CREATE OBJECT ri_exit TYPE zcl_abapgit_exit.
ENDMETHOD.
METHOD zif_abapgit_exit~allow_sap_objects.
TRY.
rv_allowed = gi_exit->allow_sap_objects( ).
CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_exit~change_local_host.
TRY.
gi_exit->change_local_host( CHANGING ct_hosts = ct_hosts ).
CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_exit~change_proxy_authentication.
TRY.
gi_exit->change_proxy_authentication(
EXPORTING
iv_repo_url = iv_repo_url
CHANGING
cv_proxy_authentication = cv_proxy_authentication ).
CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_exit~change_proxy_port.
TRY.
gi_exit->change_proxy_port(
EXPORTING
iv_repo_url = iv_repo_url
CHANGING
cv_proxy_port = cv_proxy_port ).
CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_exit~change_proxy_url.
TRY.
gi_exit->change_proxy_url(
EXPORTING
iv_repo_url = iv_repo_url
CHANGING
cv_proxy_url = cv_proxy_url ).
CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_exit~create_http_client.
TRY.
ri_client = gi_exit->create_http_client( iv_url ).
CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_exit~http_client.
TRY.
gi_exit->http_client( ii_client ).
CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_exit~change_tadir.
TRY.
gi_exit->change_tadir(
EXPORTING
iv_package = iv_package
io_log = io_log
CHANGING
ct_tadir = ct_tadir ).
CATCH cx_sy_ref_is_initial cx_sy_dyn_call_illegal_method.
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_dot_abapgit IMPLEMENTATION.
METHOD add_ignore.
DATA: lv_name TYPE string.
FIELD-SYMBOLS: <lv_ignore> LIKE LINE OF ms_data-ignore.
lv_name = iv_path && iv_filename.
READ TABLE ms_data-ignore FROM lv_name TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
RETURN.
ENDIF.
APPEND INITIAL LINE TO ms_data-ignore ASSIGNING <lv_ignore>.
<lv_ignore> = lv_name.
ENDMETHOD.
METHOD build_default.
DATA: ls_data TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit.
ls_data-master_language = sy-langu.
ls_data-starting_folder = '/src/'.
ls_data-folder_logic = zif_abapgit_dot_abapgit=>c_folder_logic-prefix.
APPEND '/.gitignore' TO ls_data-ignore.
APPEND '/LICENSE' TO ls_data-ignore.
APPEND '/README.md' TO ls_data-ignore.
APPEND '/package.json' TO ls_data-ignore.
APPEND '/.travis.yml' TO ls_data-ignore.
CREATE OBJECT ro_dot_abapgit
EXPORTING
is_data = ls_data.
ENDMETHOD.
METHOD constructor.
ms_data = is_data.
ENDMETHOD.
METHOD deserialize.
DATA: lv_xml TYPE string,
ls_data TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit.
lv_xml = zcl_abapgit_convert=>xstring_to_string_utf8( iv_xstr ).
ls_data = from_xml( lv_xml ).
CREATE OBJECT ro_dot_abapgit
EXPORTING
is_data = ls_data.
ENDMETHOD.
METHOD from_xml.
DATA: lv_xml TYPE string.
lv_xml = iv_xml.
REPLACE ALL OCCURRENCES OF '<_--28C_DATA_--29>' IN lv_xml WITH '<DATA>'.
REPLACE ALL OCCURRENCES OF '</_--28C_DATA_--29>' IN lv_xml WITH '</DATA>'.
CALL TRANSFORMATION id
OPTIONS value_handling = 'accept_data_loss'
SOURCE XML lv_xml
RESULT data = rs_data ##NO_TEXT.
IF rs_data-folder_logic IS INITIAL.
rs_data-folder_logic = zif_abapgit_dot_abapgit=>c_folder_logic-prefix.
ENDIF.
ENDMETHOD.
METHOD get_data.
rs_data = ms_data.
ENDMETHOD.
METHOD get_folder_logic.
rv_logic = ms_data-folder_logic.
ENDMETHOD.
METHOD get_master_language.
rv_language = ms_data-master_language.
ENDMETHOD.
METHOD get_signature.
rs_signature-path = zif_abapgit_definitions=>c_root_dir.
rs_signature-filename = zif_abapgit_definitions=>c_dot_abapgit.
rs_signature-sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>c_type-blob
iv_data = serialize( ) ).
ENDMETHOD. "get_signature
METHOD get_starting_folder.
rv_path = ms_data-starting_folder.
ENDMETHOD.
METHOD is_ignored.
DATA: lv_name TYPE string,
lv_starting TYPE string,
lv_dot TYPE string,
lv_count TYPE i,
lv_ignore TYPE string.
lv_name = iv_path && iv_filename.
CONCATENATE ms_data-starting_folder '*' INTO lv_starting.
CONCATENATE '/' zif_abapgit_definitions=>c_dot_abapgit INTO lv_dot.
LOOP AT ms_data-ignore INTO lv_ignore.
FIND ALL OCCURRENCES OF '/' IN lv_name MATCH COUNT lv_count.
IF lv_name CP lv_ignore
OR ( ms_data-starting_folder <> '/'
AND lv_count > 1
AND NOT lv_name CP lv_starting
AND NOT lv_name = lv_dot ).
rv_ignored = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD remove_ignore.
DATA: lv_name TYPE string.
lv_name = iv_path && iv_filename.
DELETE TABLE ms_data-ignore FROM lv_name.
ENDMETHOD.
METHOD serialize.
DATA: lv_xml TYPE string.
lv_xml = to_xml( ms_data ).
rv_xstr = zcl_abapgit_convert=>string_to_xstring_utf8( lv_xml ).
ENDMETHOD.
METHOD set_folder_logic.
ms_data-folder_logic = iv_logic.
ENDMETHOD.
METHOD set_starting_folder.
ms_data-starting_folder = iv_path.
ENDMETHOD.
METHOD to_xml.
CALL TRANSFORMATION id
OPTIONS initial_components = 'suppress'
SOURCE data = is_data
RESULT XML rv_xml.
rv_xml = zcl_abapgit_xml_pretty=>print( rv_xml ).
REPLACE FIRST OCCURRENCE
OF REGEX '<\?xml version="1\.0" encoding="[\w-]+"\?>'
IN rv_xml
WITH '<?xml version="1.0" encoding="utf-8"?>'.
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD get_requirements.
rt_requirements = ms_data-requirements.
ENDMETHOD.
METHOD set_requirements.
ms_data-requirements = it_requirements.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_DEPENDENCIES IMPLEMENTATION.
METHOD get_ddls_dependencies.
TYPES: BEGIN OF ty_ddls_name.
INCLUDE TYPE ddsymtab.
TYPES: END OF ty_ddls_name.
TYPES: tty_ddls_names TYPE STANDARD TABLE OF ty_ddls_name
WITH NON-UNIQUE DEFAULT KEY.
DATA: lt_ddls_name TYPE tty_ddls_names,
ls_ddls_name LIKE LINE OF lt_ddls_name.
ls_ddls_name-name = iv_ddls_name.
INSERT ls_ddls_name INTO TABLE lt_ddls_name.
PERFORM ('DDLS_GET_DEP') IN PROGRAM ('RADMASDL')
TABLES lt_ddls_name rt_dependency.
ENDMETHOD.
METHOD resolve.
DATA: lv_tabclass TYPE dd02l-tabclass.
FIELD-SYMBOLS: <ls_tadir> LIKE LINE OF ct_tadir.
LOOP AT ct_tadir ASSIGNING <ls_tadir>.
CASE <ls_tadir>-object.
WHEN 'DEVC'.
<ls_tadir>-korrnum = '9990'.
WHEN 'IATU'.
<ls_tadir>-korrnum = '5500'.
WHEN 'IARP'.
<ls_tadir>-korrnum = '5510'.
WHEN 'IASP'.
<ls_tadir>-korrnum = '5520'.
WHEN 'SUSC'.
<ls_tadir>-korrnum = '5000'.
WHEN 'TTYP' OR 'TABL' OR 'VIEW'.
SELECT SINGLE tabclass FROM dd02l
INTO lv_tabclass
WHERE tabname = <ls_tadir>-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
IF sy-subrc = 0 AND lv_tabclass = 'APPEND'.
<ls_tadir>-korrnum = '6500'.
ELSE.
<ls_tadir>-korrnum = '7000'.
ENDIF.
WHEN 'DTEL'.
<ls_tadir>-korrnum = '8000'.
WHEN 'PARA'.
<ls_tadir>-korrnum = '8100'.
WHEN 'DOMA'.
<ls_tadir>-korrnum = '9000'.
WHEN 'PROG'.
SELECT COUNT(*) FROM reposrc
WHERE progname = <ls_tadir>-obj_name
AND r3state = 'A'
AND subc = 'I'.
IF sy-subrc = 0.
<ls_tadir>-korrnum = '2000'.
ELSE.
<ls_tadir>-korrnum = '1000'.
ENDIF.
WHEN 'IDOC'.
<ls_tadir>-korrnum = '2000'.
WHEN 'IEXT'.
<ls_tadir>-korrnum = '1500'.
WHEN OTHERS.
<ls_tadir>-korrnum = '1000'.
ENDCASE.
ENDLOOP.
resolve_ddic( CHANGING ct_tadir = ct_tadir ).
resolve_packages( CHANGING ct_tadir = ct_tadir ).
SORT ct_tadir BY korrnum ASCENDING.
ENDMETHOD.
METHOD resolve_ddic.
TYPES: BEGIN OF ty_edge,
from TYPE ty_item,
to TYPE ty_item,
END OF ty_edge.
DATA: lt_nodes TYPE TABLE OF ty_item,
lt_edges TYPE TABLE OF ty_edge,
lt_findstrings TYPE TABLE OF rsfind,
lv_plus TYPE i VALUE 1,
lv_find_obj_cls TYPE euobj-id,
lv_index TYPE i,
lv_before TYPE i,
lt_founds TYPE TABLE OF rsfindlst,
lt_scope TYPE STANDARD TABLE OF seu_obj,
lt_dependency TYPE tty_dedenpency.
FIELD-SYMBOLS: <ls_tadir_ddls> TYPE zif_abapgit_definitions=>ty_tadir,
<ls_dependency> TYPE ty_dependency,
<ls_tadir_dependent> TYPE zif_abapgit_definitions=>ty_tadir,
<ls_tadir> LIKE LINE OF ct_tadir,
<ls_edge> LIKE LINE OF lt_edges,
<ls_found> LIKE LINE OF lt_founds,
<ls_node> LIKE LINE OF lt_nodes.
LOOP AT ct_tadir ASSIGNING <ls_tadir>
WHERE object = 'TABL'
OR object = 'TTYP'.
APPEND INITIAL LINE TO lt_nodes ASSIGNING <ls_node>.
<ls_node>-obj_name = <ls_tadir>-obj_name.
<ls_node>-obj_type = <ls_tadir>-object.
ENDLOOP.
APPEND 'TABL' TO lt_scope.
APPEND 'STRU' TO lt_scope.
APPEND 'TTYP' TO lt_scope.
LOOP AT lt_nodes ASSIGNING <ls_node>.
CLEAR lt_findstrings.
APPEND <ls_node>-obj_name TO lt_findstrings.
lv_find_obj_cls = <ls_node>-obj_type.
CALL FUNCTION 'RS_EU_CROSSREF'
EXPORTING
i_find_obj_cls = lv_find_obj_cls
TABLES
i_findstrings = lt_findstrings
o_founds = lt_founds
i_scope_object_cls = lt_scope
EXCEPTIONS
not_executed = 1
not_found = 2
illegal_object = 3
no_cross_for_this_object = 4
batch = 5
batchjob_error = 6
wrong_type = 7
object_not_exist = 8
OTHERS = 9.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
LOOP AT lt_founds ASSIGNING <ls_found>.
APPEND INITIAL LINE TO lt_edges ASSIGNING <ls_edge>.
<ls_edge>-from = <ls_node>.
<ls_edge>-to-obj_name = <ls_found>-object.
CASE <ls_found>-object_cls.
WHEN 'DS'
OR 'DT'.
<ls_edge>-to-obj_type = 'TABL'.
WHEN 'DA'.
<ls_edge>-to-obj_type = 'TTYP'.
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'resolve_ddic, unknown object_cls' ).
ENDCASE.
ENDLOOP.
ENDLOOP.
LOOP AT ct_tadir ASSIGNING <ls_tadir_ddls>
WHERE object = 'DDLS'.
CLEAR: lt_dependency.
APPEND INITIAL LINE TO lt_nodes ASSIGNING <ls_node>.
<ls_node>-obj_name = <ls_tadir_ddls>-obj_name.
<ls_node>-obj_type = <ls_tadir_ddls>-object.
lt_dependency = get_ddls_dependencies( <ls_tadir_ddls>-obj_name ).
LOOP AT lt_dependency ASSIGNING <ls_dependency>
WHERE deptyp = 'DDLS'
AND refname = <ls_tadir_ddls>-obj_name.
READ TABLE ct_tadir ASSIGNING <ls_tadir_dependent>
WITH KEY pgmid = 'R3TR'
object = 'DDLS'
obj_name = <ls_dependency>-depname
BINARY SEARCH.
CHECK sy-subrc = 0.
APPEND INITIAL LINE TO lt_edges ASSIGNING <ls_edge>.
<ls_edge>-from = <ls_node>.
<ls_edge>-to-obj_name = <ls_dependency>-depname.
<ls_edge>-to-obj_type = 'DDLS'.
ENDLOOP.
ENDLOOP.
DO.
lv_before = lines( lt_nodes ).
LOOP AT lt_nodes ASSIGNING <ls_node>.
lv_index = sy-tabix.
READ TABLE lt_edges WITH KEY
from-obj_name = <ls_node>-obj_name
from-obj_type = <ls_node>-obj_type
TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
LOOP AT ct_tadir ASSIGNING <ls_tadir>
WHERE obj_name = <ls_node>-obj_name
AND object = <ls_node>-obj_type.
<ls_tadir>-korrnum = <ls_tadir>-korrnum + lv_plus.
CONDENSE <ls_tadir>-korrnum.
ENDLOOP.
DELETE lt_edges
WHERE to-obj_name = <ls_node>-obj_name
AND to-obj_type = <ls_node>-obj_type.
DELETE lt_nodes INDEX lv_index.
EXIT. " make sure the sequence is fixed
ENDIF.
ENDLOOP.
IF lv_before = lines( lt_nodes ).
EXIT.
ENDIF.
lv_plus = lv_plus + 1.
ENDDO.
ENDMETHOD. "resolve_ddic
METHOD resolve_packages.
DATA: lt_subpackages TYPE zif_abapgit_sap_package=>ty_devclass_tt.
FIELD-SYMBOLS: <ls_tadir> LIKE LINE OF ct_tadir,
<lv_subpackage> LIKE LINE OF lt_subpackages,
<ls_tadir_subpackage> LIKE LINE OF ct_tadir.
" List subpackage before corresponding superpackage
LOOP AT ct_tadir ASSIGNING <ls_tadir>
WHERE object = 'DEVC'.
lt_subpackages = zcl_abapgit_factory=>get_sap_package( |{ <ls_tadir>-obj_name }| )->list_subpackages( ).
LOOP AT lt_subpackages ASSIGNING <lv_subpackage>.
READ TABLE ct_tadir ASSIGNING <ls_tadir_subpackage>
WITH KEY object = 'DEVC'
obj_name = <lv_subpackage>.
IF sy-subrc = 0.
<ls_tadir_subpackage>-korrnum = condense( |{ <ls_tadir_subpackage>-korrnum - 1 }| ).
ENDIF.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_default_transport IMPLEMENTATION.
METHOD clear.
CALL FUNCTION 'TR_TASK_RESET'
EXPORTING
iv_username = is_default_task-username
iv_order = is_default_task-ordernum
iv_task = is_default_task-tasknum
iv_dialog = abap_false
EXCEPTIONS
invalid_username = 1
invalid_order = 2
invalid_task = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from TR_TASK_RESET { sy-subrc }| ).
ENDIF.
ENDMETHOD.
METHOD constructor.
store( ).
ENDMETHOD.
METHOD get.
DATA: lt_e070use TYPE STANDARD TABLE OF e070use.
CALL FUNCTION 'TR_TASK_GET'
TABLES
tt_e070use = lt_e070use
EXCEPTIONS
invalid_username = 1
invalid_category = 2
invalid_client = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from TR_TASK_GET { sy-subrc }| ).
ENDIF.
READ TABLE lt_e070use INTO rs_default_task
INDEX 1.
ENDMETHOD.
METHOD get_instance.
IF mo_instance IS NOT BOUND.
CREATE OBJECT mo_instance.
ENDIF.
ro_instance = mo_instance.
ENDMETHOD.
METHOD reset.
DATA: ls_default_task TYPE e070use.
IF mv_is_set_by_abapgit = abap_false.
" if the default transport request task isn't set
" by us there is nothing to do.
RETURN.
ENDIF.
CLEAR mv_is_set_by_abapgit.
ls_default_task = get( ).
IF ls_default_task IS NOT INITIAL.
clear( ls_default_task ).
ENDIF.
restore( ).
ENDMETHOD.
METHOD restore.
IF ms_save IS INITIAL.
" There wasn't a default transport request before
" so we needn't restore anything.
RETURN.
ENDIF.
CALL FUNCTION 'TR_TASK_SET'
EXPORTING
iv_order = ms_save-ordernum
iv_task = ms_save-tasknum
EXCEPTIONS
invalid_username = 1
invalid_category = 2
invalid_client = 3
invalid_validdays = 4
invalid_order = 5
invalid_task = 6
OTHERS = 7.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from TR_TASK_SET { sy-subrc }| ).
ENDIF.
ENDMETHOD.
METHOD set.
" checks whether object changes of the package are rerorded in transport
" requests. If true then we set the default task, so that no annoying
" transport request popups are shown while deserializing.
IF mv_is_set_by_abapgit = abap_true.
" the default transport request task is already set by us
" -> no reason to do it again.
RETURN.
ENDIF.
IF iv_transport IS INITIAL.
zcx_abapgit_exception=>raise( |No transport request was supplied| ).
ENDIF.
set_internal( iv_transport ).
mv_is_set_by_abapgit = abap_true.
ENDMETHOD.
METHOD set_internal.
CALL FUNCTION 'TR_TASK_SET'
EXPORTING
iv_order = iv_transport
EXCEPTIONS
invalid_username = 1
invalid_category = 2
invalid_client = 3
invalid_validdays = 4
invalid_order = 5
invalid_task = 6
OTHERS = 7.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from TR_TASK_SET { sy-subrc }| ).
ENDIF.
ENDMETHOD.
METHOD store.
ms_save = get( ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_code_inspector IMPLEMENTATION.
METHOD constructor.
mv_package = iv_package.
mv_check_variant_name = iv_check_variant_name.
ENDMETHOD.
METHOD create_inspection.
cl_ci_inspection=>create(
EXPORTING
p_user = sy-uname
p_name = ''
RECEIVING
p_ref = ro_inspection
EXCEPTIONS
locked = 1
error_in_enqueue = 2
not_authorized = 3
OTHERS = 4 ).
ASSERT sy-subrc = 0.
ro_inspection->set(
p_chkv = io_variant
p_objs = io_set ).
ENDMETHOD.
METHOD create_objectset.
DATA: lt_objs TYPE scit_objs,
lt_packages TYPE ty_tdevc_tt.
lt_packages = find_all_subpackages( mv_package ).
IF lines( lt_packages ) = 0.
RETURN.
ENDIF.
SELECT object AS objtype obj_name AS objname
FROM tadir
INTO CORRESPONDING FIELDS OF TABLE lt_objs
FOR ALL ENTRIES IN lt_packages
WHERE devclass = lt_packages-devclass
AND delflag = abap_false
AND pgmid = 'R3TR'. "#EC CI_GENBUFF
ro_set = cl_ci_objectset=>save_from_list( lt_objs ).
ENDMETHOD.
METHOD create_variant.
IF mv_check_variant_name IS INITIAL.
zcx_abapgit_exception=>raise( |No check variant supplied.| ).
ENDIF.
cl_ci_checkvariant=>get_ref(
EXPORTING
p_user = ''
p_name = mv_check_variant_name
RECEIVING
p_ref = ro_variant
EXCEPTIONS
chkv_not_exists = 1
missing_parameter = 2
OTHERS = 3 ).
CASE sy-subrc.
WHEN 1.
zcx_abapgit_exception=>raise( |Check variant { mv_check_variant_name } doesn't exist| ).
WHEN 2.
zcx_abapgit_exception=>raise( |Parameter missing for check variant { mv_check_variant_name }| ).
ENDCASE.
ENDMETHOD.
METHOD find_all_subpackages.
DATA: ls_package LIKE LINE OF rt_packages,
lt_found LIKE rt_packages,
lt_sub LIKE rt_packages.
SELECT SINGLE * FROM tdevc INTO ls_package WHERE devclass = iv_package.
ASSERT sy-subrc = 0.
APPEND ls_package TO rt_packages.
SELECT * FROM tdevc APPENDING TABLE lt_sub
WHERE parentcl = ls_package-devclass.
LOOP AT lt_sub INTO ls_package.
lt_found = find_all_subpackages( ls_package-devclass ).
APPEND LINES OF lt_found TO rt_packages.
ENDLOOP.
ENDMETHOD.
METHOD run_inspection.
io_inspection->run(
EXCEPTIONS
invalid_check_version = 1
OTHERS = 2 ).
ASSERT sy-subrc = 0.
io_inspection->plain_list(
IMPORTING
p_list = rt_list ).
ENDMETHOD.
METHOD zif_abapgit_code_inspector~run.
DATA: lo_set TYPE REF TO cl_ci_objectset,
lo_variant TYPE REF TO cl_ci_checkvariant.
lo_set = create_objectset( ).
lo_variant = create_variant( ).
mo_inspection = create_inspection(
io_set = lo_set
io_variant = lo_variant ).
rt_list = run_inspection( mo_inspection ).
ENDMETHOD.
METHOD validate_check_variant.
cl_ci_checkvariant=>get_ref(
EXPORTING
p_user = ''
p_name = iv_check_variant_name
EXCEPTIONS
chkv_not_exists = 1
missing_parameter = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |No valid check variant { iv_check_variant_name }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_code_inspector~get_inspection.
ro_inspection = mo_inspection.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_BRANCH_OVERVIEW IMPLEMENTATION.
METHOD constructor.
DATA: lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt.
CLEAR mt_branches.
lt_objects = get_git_objects( io_repo ).
mt_commits = parse_commits( lt_objects ).
parse_annotated_tags( lt_objects ).
CLEAR lt_objects.
determine_branch( ).
determine_merges( ).
determine_tags( ).
fixes( ).
SORT mt_commits BY time ASCENDING.
ENDMETHOD.
METHOD determine_branch.
CONSTANTS: lc_head TYPE string VALUE 'HEAD'.
DATA: lv_name TYPE string.
FIELD-SYMBOLS: <ls_branch> LIKE LINE OF mt_branches,
<ls_head> LIKE LINE OF mt_branches,
<ls_commit> LIKE LINE OF mt_commits,
<ls_create> LIKE LINE OF <ls_commit>-create.
READ TABLE mt_branches ASSIGNING <ls_head> WITH KEY name = lc_head.
ASSERT sy-subrc = 0.
LOOP AT mt_branches ASSIGNING <ls_branch>
WHERE sha1 = <ls_head>-sha1 AND name <> lc_head.
<ls_head>-name = <ls_branch>-name.
DELETE mt_branches INDEX sy-tabix.
EXIT.
ENDLOOP.
LOOP AT mt_branches ASSIGNING <ls_branch>.
lv_name = <ls_branch>-name+11.
READ TABLE mt_commits ASSIGNING <ls_commit> WITH KEY sha1 = <ls_branch>-sha1.
ASSERT sy-subrc = 0.
DO.
IF <ls_commit>-branch IS INITIAL.
<ls_commit>-branch = lv_name.
ELSE.
APPEND INITIAL LINE TO <ls_commit>-create ASSIGNING <ls_create>.
<ls_create>-name = lv_name.
<ls_create>-parent = <ls_commit>-branch.
EXIT.
ENDIF.
IF <ls_commit>-parent1 IS INITIAL.
EXIT.
ELSE.
READ TABLE mt_commits ASSIGNING <ls_commit>
WITH KEY sha1 = <ls_commit>-parent1.
ASSERT sy-subrc = 0.
ENDIF.
ENDDO.
ENDLOOP.
ENDMETHOD.
METHOD determine_merges.
FIELD-SYMBOLS: <ls_merged> LIKE LINE OF mt_commits,
<ls_commit> LIKE LINE OF mt_commits.
SORT mt_commits BY time DESCENDING.
LOOP AT mt_commits ASSIGNING <ls_commit> WHERE NOT parent2 IS INITIAL.
ASSERT NOT <ls_commit>-branch IS INITIAL.
READ TABLE mt_commits ASSIGNING <ls_merged> WITH KEY sha1 = <ls_commit>-parent2.
IF sy-subrc = 0.
<ls_commit>-merge = <ls_merged>-branch.
WHILE <ls_merged>-branch IS INITIAL.
<ls_merged>-branch = <ls_commit>-branch.
READ TABLE mt_commits ASSIGNING <ls_merged> WITH KEY sha1 = <ls_merged>-parent1.
IF sy-subrc <> 0.
EXIT.
ENDIF.
ENDWHILE.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD determine_tags.
DATA: lv_tag TYPE LINE OF zif_abapgit_definitions=>ty_commit-tags.
FIELD-SYMBOLS: <ls_tag> LIKE LINE OF mt_tags,
<ls_commit> LIKE LINE OF mt_commits.
LOOP AT mt_tags ASSIGNING <ls_tag>.
IF <ls_tag>-type = zif_abapgit_definitions=>c_git_branch_type-lightweight_tag.
READ TABLE mt_commits WITH KEY sha1 = <ls_tag>-sha1
ASSIGNING <ls_commit>. "#EC CI_SUBRC
ELSEIF <ls_tag>-type = zif_abapgit_definitions=>c_git_branch_type-annotated_tag.
READ TABLE mt_commits WITH KEY sha1 = <ls_tag>-object
ASSIGNING <ls_commit>.
ENDIF.
CHECK sy-subrc = 0.
lv_tag = zcl_abapgit_tag=>remove_tag_prefix( <ls_tag>-name ).
INSERT lv_tag INTO TABLE <ls_commit>-tags.
ENDLOOP.
ENDMETHOD.
METHOD fixes.
FIELD-SYMBOLS: <ls_commit> LIKE LINE OF mt_commits.
LOOP AT mt_commits ASSIGNING <ls_commit> WHERE NOT merge IS INITIAL.
IF <ls_commit>-branch = <ls_commit>-merge.
CLEAR <ls_commit>-merge.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD get_git_objects.
DATA: lo_branch_list TYPE REF TO zcl_abapgit_git_branch_list,
lo_progress TYPE REF TO zcl_abapgit_progress,
lt_branches_and_tags TYPE zif_abapgit_definitions=>ty_git_branch_list_tt,
lt_tags TYPE zif_abapgit_definitions=>ty_git_branch_list_tt,
ls_tag LIKE LINE OF mt_tags.
FIELD-SYMBOLS: <ls_branch> LIKE LINE OF lt_tags.
CREATE OBJECT lo_progress
EXPORTING
iv_total = 1.
lo_progress->show(
iv_current = 1
iv_text = |Get git objects { io_repo->get_name( ) }| ) ##NO_TEXT.
"TODO refactor
lo_branch_list = zcl_abapgit_git_transport=>branches( io_repo->get_url( ) ).
mt_branches = lo_branch_list->get_branches_only( ).
INSERT LINES OF mt_branches INTO TABLE lt_branches_and_tags.
lt_tags = lo_branch_list->get_tags_only( ).
INSERT LINES OF lt_tags INTO TABLE lt_branches_and_tags.
LOOP AT lt_tags ASSIGNING <ls_branch>.
IF <ls_branch>-name CP '*^{}'.
CONTINUE.
ENDIF.
MOVE-CORRESPONDING <ls_branch> TO ls_tag.
INSERT ls_tag INTO TABLE mt_tags.
ENDLOOP.
zcl_abapgit_git_transport=>upload_pack(
EXPORTING
iv_url = io_repo->get_url( )
iv_branch_name = io_repo->get_branch_name( )
iv_deepen = abap_false
it_branches = lt_branches_and_tags
IMPORTING
et_objects = rt_objects ).
DELETE rt_objects WHERE type = zif_abapgit_definitions=>c_type-blob.
ENDMETHOD.
METHOD parse_annotated_tags.
DATA: ls_raw TYPE zcl_abapgit_git_pack=>ty_tag.
FIELD-SYMBOLS: <ls_object> LIKE LINE OF it_objects,
<ls_tag> LIKE LINE OF mt_tags.
LOOP AT it_objects ASSIGNING <ls_object> USING KEY type
WHERE type = zif_abapgit_definitions=>c_type-tag.
ls_raw = zcl_abapgit_git_pack=>decode_tag( <ls_object>-data ).
READ TABLE mt_tags ASSIGNING <ls_tag>
WITH KEY sha1 = <ls_object>-sha1.
ASSERT sy-subrc = 0.
<ls_tag>-name = |refs/tags/{ ls_raw-tag }|.
<ls_tag>-sha1 = <ls_object>-sha1.
<ls_tag>-object = ls_raw-object.
<ls_tag>-type = zif_abapgit_definitions=>c_git_branch_type-annotated_tag.
<ls_tag>-display_name = ls_raw-tag.
<ls_tag>-tagger_name = ls_raw-tagger_name.
<ls_tag>-tagger_email = ls_raw-tagger_email.
<ls_tag>-message = ls_raw-message.
<ls_tag>-body = ls_raw-body.
ENDLOOP.
ENDMETHOD.
METHOD parse_commits.
DATA: ls_commit LIKE LINE OF mt_commits,
lt_body TYPE STANDARD TABLE OF string WITH DEFAULT KEY,
ls_raw TYPE zcl_abapgit_git_pack=>ty_commit.
FIELD-SYMBOLS: <ls_object> LIKE LINE OF it_objects.
LOOP AT it_objects ASSIGNING <ls_object> USING KEY type
WHERE type = zif_abapgit_definitions=>c_type-commit.
ls_raw = zcl_abapgit_git_pack=>decode_commit( <ls_object>-data ).
CLEAR ls_commit.
ls_commit-sha1 = <ls_object>-sha1.
ls_commit-parent1 = ls_raw-parent.
ls_commit-parent2 = ls_raw-parent2.
SPLIT ls_raw-body AT zif_abapgit_definitions=>c_newline INTO TABLE lt_body.
READ TABLE lt_body WITH KEY table_line = ' -----END PGP SIGNATURE-----' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
DELETE lt_body TO sy-tabix.
DELETE lt_body TO 2.
ENDIF.
READ TABLE lt_body INDEX 1 INTO ls_commit-message. "#EC CI_SUBRC
FIND REGEX zif_abapgit_definitions=>c_author_regex IN ls_raw-author
SUBMATCHES
ls_commit-author
ls_commit-email
ls_commit-time ##NO_TEXT.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error author regex' ).
ENDIF.
APPEND ls_commit TO rt_commits.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_branch_overview~compress.
DEFINE _compress.
IF lines( lt_temp ) >= 10.
READ TABLE lt_temp ASSIGNING <ls_temp> INDEX 1.
ASSERT sy-subrc = 0.
APPEND INITIAL LINE TO rt_commits ASSIGNING <ls_new>.
<ls_new>-time = <ls_temp>-time.
<ls_new>-message = |Compressed, { lines( lt_temp ) } commits|.
<ls_new>-branch = lv_name.
<ls_new>-compressed = abap_true.
ELSE.
APPEND LINES OF lt_temp TO rt_commits.
ENDIF.
END-OF-DEFINITION.
DATA: lv_previous TYPE i,
lv_index TYPE i,
lv_name TYPE string,
lt_temp LIKE it_commits.
FIELD-SYMBOLS: <ls_branch> LIKE LINE OF mt_branches,
<ls_new> LIKE LINE OF rt_commits,
<ls_temp> LIKE LINE OF lt_temp,
<ls_commit> LIKE LINE OF it_commits.
LOOP AT mt_branches ASSIGNING <ls_branch>.
CLEAR lt_temp.
lv_name = <ls_branch>-name+11.
LOOP AT it_commits ASSIGNING <ls_commit>
WHERE branch = lv_name.
lv_index = sy-tabix.
IF NOT <ls_commit>-merge IS INITIAL
OR NOT <ls_commit>-create IS INITIAL.
lv_previous = -1.
ENDIF.
IF lv_previous + 1 <> sy-tabix.
_compress.
CLEAR lt_temp.
ENDIF.
lv_previous = lv_index.
APPEND <ls_commit> TO lt_temp.
ENDLOOP.
_compress.
ENDLOOP.
SORT rt_commits BY time ASCENDING.
ENDMETHOD.
METHOD zif_abapgit_branch_overview~get_branches.
rt_branches = mt_branches.
ENDMETHOD.
METHOD zif_abapgit_branch_overview~get_commits.
rt_commits = mt_commits.
ENDMETHOD.
METHOD zif_abapgit_branch_overview~get_tags.
rt_tags = mt_tags.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_AUTH IMPLEMENTATION.
METHOD is_allowed.
DATA: li_auth TYPE REF TO zif_abapgit_auth.
TRY.
CREATE OBJECT li_auth TYPE ('ZCL_ABAPGIT_AUTH_EXIT').
rv_allowed = li_auth->is_allowed( iv_authorization = iv_authorization
iv_param = iv_param ).
CATCH cx_sy_create_object_error.
rv_allowed = abap_true.
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_XML_PRETTY IMPLEMENTATION.
METHOD print.
DATA: li_ixml TYPE REF TO if_ixml,
li_xml_doc TYPE REF TO if_ixml_document,
li_stream_factory TYPE REF TO if_ixml_stream_factory,
li_istream TYPE REF TO if_ixml_istream,
li_parser TYPE REF TO if_ixml_parser,
li_ostream TYPE REF TO if_ixml_ostream,
li_renderer TYPE REF TO if_ixml_renderer.
ASSERT NOT iv_xml IS INITIAL.
li_ixml = cl_ixml=>create( ).
li_xml_doc = li_ixml->create_document( ).
li_stream_factory = li_ixml->create_stream_factory( ).
li_istream = li_stream_factory->create_istream_string( iv_xml ).
li_parser = li_ixml->create_parser( stream_factory = li_stream_factory
istream = li_istream
document = li_xml_doc ).
li_parser->set_normalizing( abap_true ).
IF li_parser->parse( ) <> 0.
IF iv_ignore_errors = abap_true.
rv_xml = iv_xml.
RETURN.
ELSE.
zcx_abapgit_exception=>raise( 'error parsing xml' ).
ENDIF.
ENDIF.
li_istream->close( ).
li_ostream = li_stream_factory->create_ostream_cstring( rv_xml ).
li_renderer = li_ixml->create_renderer( ostream = li_ostream
document = li_xml_doc ).
li_renderer->set_normalizing( boolc( iv_unpretty = abap_false ) ).
li_renderer->render( ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_XML_OUTPUT IMPLEMENTATION.
METHOD add.
DATA: li_node TYPE REF TO if_ixml_node,
li_doc TYPE REF TO if_ixml_document,
lt_stab TYPE abap_trans_srcbind_tab.
FIELD-SYMBOLS: <ls_stab> LIKE LINE OF lt_stab.
ASSERT NOT iv_name IS INITIAL.
IF ig_data IS INITIAL.
RETURN.
ENDIF.
APPEND INITIAL LINE TO lt_stab ASSIGNING <ls_stab>.
<ls_stab>-name = iv_name.
GET REFERENCE OF ig_data INTO <ls_stab>-value.
li_doc = cl_ixml=>create( )->create_document( ).
CALL TRANSFORMATION id
OPTIONS initial_components = 'suppress'
SOURCE (lt_stab)
RESULT XML li_doc.
li_node = mi_xml_doc->get_root( )->get_first_child( ).
IF li_node IS BOUND.
mi_xml_doc->get_root( )->get_first_child( )->get_first_child( )->append_child(
li_doc->get_root( )->get_first_child( )->get_first_child( )->get_first_child( ) ).
ELSE.
mi_xml_doc->get_root( )->append_child( li_doc->get_root( )->get_first_child( ) ).
ENDIF.
ENDMETHOD.
METHOD add_xml.
DATA: li_element TYPE REF TO if_ixml_element.
li_element = mi_xml_doc->create_element( iv_name ).
li_element->append_child( ii_xml ).
mi_xml_doc->get_root( )->get_first_child( )->get_first_child( )->append_child( li_element ).
ENDMETHOD.
METHOD build_asx_node.
DATA: li_attr TYPE REF TO if_ixml_attribute.
ri_element = mi_xml_doc->create_element_ns(
name = 'abap'
prefix = 'asx' ).
li_attr = mi_xml_doc->create_attribute_ns( 'version' ).
li_attr->if_ixml_node~set_value( '1.0' ).
ri_element->set_attribute_node_ns( li_attr ).
li_attr = mi_xml_doc->create_attribute_ns(
name = 'asx'
prefix = 'xmlns' ).
li_attr->if_ixml_node~set_value( 'http://www.sap.com/abapxml' ).
ri_element->set_attribute_node_ns( li_attr ).
ENDMETHOD.
METHOD render.
DATA: li_git TYPE REF TO if_ixml_element,
li_abap TYPE REF TO if_ixml_element.
IF mi_raw IS INITIAL.
li_abap ?= mi_xml_doc->get_root( )->get_first_child( ).
mi_xml_doc->get_root( )->remove_child( li_abap ).
IF li_abap IS INITIAL.
li_abap = build_asx_node( ).
ENDIF.
ELSE.
li_abap = mi_raw.
ENDIF.
li_git = mi_xml_doc->create_element( c_abapgit_tag ).
li_git->set_attribute( name = c_attr_version value = zif_abapgit_version=>gc_xml_version ).
IF NOT is_metadata IS INITIAL.
li_git->set_attribute( name = c_attr_serializer
value = is_metadata-class ).
li_git->set_attribute( name = c_attr_serializer_version
value = is_metadata-version ).
ENDIF.
li_git->append_child( li_abap ).
mi_xml_doc->get_root( )->append_child( li_git ).
rv_xml = to_xml( iv_normalize ).
ENDMETHOD.
METHOD set_raw.
mi_raw = ii_raw.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_XML_INPUT IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
parse( iv_xml ).
fix_xml( ).
ENDMETHOD.
METHOD fix_xml.
DATA: li_git TYPE REF TO if_ixml_element,
li_abap TYPE REF TO if_ixml_node.
li_git ?= mi_xml_doc->find_from_name_ns( depth = 0 name = c_abapgit_tag ).
li_abap = li_git->get_first_child( ).
mi_xml_doc->get_root( )->remove_child( li_git ).
mi_xml_doc->get_root( )->append_child( li_abap ).
ENDMETHOD.
METHOD get_metadata.
rs_metadata = ms_metadata.
ENDMETHOD.
METHOD get_raw.
ri_raw = mi_xml_doc.
ENDMETHOD.
METHOD read.
DATA: lx_error TYPE REF TO cx_transformation_error,
lt_rtab TYPE abap_trans_resbind_tab.
FIELD-SYMBOLS: <ls_rtab> LIKE LINE OF lt_rtab.
ASSERT NOT iv_name IS INITIAL.
CLEAR cg_data. "Initialize result to avoid problems with empty values
APPEND INITIAL LINE TO lt_rtab ASSIGNING <ls_rtab>.
<ls_rtab>-name = iv_name.
GET REFERENCE OF cg_data INTO <ls_rtab>-value.
TRY.
CALL TRANSFORMATION id
OPTIONS value_handling = 'accept_data_loss'
SOURCE XML mi_xml_doc
RESULT (lt_rtab) ##no_text.
CATCH cx_transformation_error INTO lx_error.
zcx_abapgit_exception=>raise( lx_error->if_message~get_text( ) ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_XML IMPLEMENTATION.
METHOD constructor.
mi_ixml = cl_ixml=>create( ).
mi_xml_doc = mi_ixml->create_document( ).
ENDMETHOD.
METHOD display_xml_error.
DATA: lv_version TYPE string.
lv_version = |abapGit version: { zif_abapgit_version=>gc_abap_version }|.
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
titel = 'abapGit XML version mismatch'
txt1 = 'abapGit XML version mismatch'
txt2 = 'See http://larshp.github.io/abapGit/other-xml-mismatch.html'
txt3 = lv_version. "#EC NOTEXT
zcx_abapgit_exception=>raise( 'XML error' ).
ENDMETHOD.
METHOD error.
DATA: lv_error TYPE i,
lv_txt1 TYPE string,
lv_txt2 TYPE string,
lv_txt3 TYPE string,
lv_times TYPE i,
li_error TYPE REF TO if_ixml_parse_error.
IF ii_parser->num_errors( ) <> 0.
lv_times = ii_parser->num_errors( ).
DO lv_times TIMES.
lv_error = sy-index - 1.
li_error = ii_parser->get_error( lv_error ).
lv_txt1 = li_error->get_column( ).
CONCATENATE 'Column:' lv_txt1 INTO lv_txt1. "#EC NOTEXT
lv_txt2 = li_error->get_line( ).
CONCATENATE 'Line:' lv_txt2 INTO lv_txt2. "#EC NOTEXT
lv_txt3 = li_error->get_reason( ).
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
titel = 'Error from XML parser' "#EC NOTEXT
txt1 = lv_txt1
txt2 = lv_txt2
txt3 = lv_txt3.
ENDDO.
ENDIF.
zcx_abapgit_exception=>raise( 'Error while parsing XML' ).
ENDMETHOD.
METHOD parse.
DATA: li_stream_factory TYPE REF TO if_ixml_stream_factory,
li_istream TYPE REF TO if_ixml_istream,
li_element TYPE REF TO if_ixml_element,
li_version TYPE REF TO if_ixml_node,
li_parser TYPE REF TO if_ixml_parser.
ASSERT NOT iv_xml IS INITIAL.
li_stream_factory = mi_ixml->create_stream_factory( ).
li_istream = li_stream_factory->create_istream_string( iv_xml ).
li_parser = mi_ixml->create_parser( stream_factory = li_stream_factory
istream = li_istream
document = mi_xml_doc ).
li_parser->set_normalizing( iv_normalize ).
IF li_parser->parse( ) <> 0.
error( li_parser ).
ENDIF.
li_istream->close( ).
li_element = mi_xml_doc->find_from_name_ns( depth = 0 name = c_abapgit_tag ).
li_version = li_element->if_ixml_node~get_attributes(
)->get_named_item_ns( c_attr_version ) ##no_text.
IF li_version->get_value( ) <> zif_abapgit_version=>gc_xml_version.
display_xml_error( ).
ENDIF.
ms_metadata-class = li_element->get_attribute_ns( c_attr_serializer ).
ms_metadata-version = li_element->get_attribute_ns( c_attr_serializer_version ).
ENDMETHOD.
METHOD to_xml.
DATA: li_ostream TYPE REF TO if_ixml_ostream,
li_renderer TYPE REF TO if_ixml_renderer,
li_streamfactory TYPE REF TO if_ixml_stream_factory.
li_streamfactory = mi_ixml->create_stream_factory( ).
li_ostream = li_streamfactory->create_ostream_cstring( rv_xml ).
li_renderer = mi_ixml->create_renderer( ostream = li_ostream
document = mi_xml_doc ).
li_renderer->set_normalizing( iv_normalize ).
li_renderer->render( ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_user_master_record IMPLEMENTATION.
METHOD constructor.
DATA: lt_return TYPE TABLE OF bapiret2,
ls_address TYPE bapiaddr3,
lt_smtp TYPE TABLE OF bapiadsmtp,
ls_smtp TYPE bapiadsmtp.
CALL FUNCTION 'BAPI_USER_GET_DETAIL'
EXPORTING
username = iv_user
IMPORTING
address = ls_address
TABLES
return = lt_return
addsmtp = lt_smtp.
SORT lt_smtp BY consnumber ASCENDING.
LOOP AT lt_smtp INTO ls_smtp.
ms_user-email = ls_smtp-e_mail.
EXIT.
ENDLOOP.
ms_user-name = ls_address-fullname.
ENDMETHOD.
METHOD get_email.
rv_email = ms_user-email.
ENDMETHOD.
METHOD get_instance.
DATA: ls_user TYPE ty_user.
FIELD-SYMBOLS: <ls_user> TYPE ty_user.
READ TABLE mt_user ASSIGNING <ls_user>
WITH KEY user = iv_user.
IF sy-subrc <> 0.
ls_user-user = iv_user.
CREATE OBJECT ls_user-o_user
EXPORTING
iv_user = iv_user.
INSERT ls_user
INTO TABLE mt_user
ASSIGNING <ls_user>.
ENDIF.
ro_user = <ls_user>-o_user.
ENDMETHOD.
METHOD get_name.
rv_name = ms_user-name.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_URL IMPLEMENTATION.
METHOD host.
regex( EXPORTING iv_url = iv_url
IMPORTING ev_host = rv_host ).
ENDMETHOD.
METHOD name.
regex( EXPORTING iv_url = iv_url
IMPORTING ev_name = rv_name ).
ENDMETHOD.
METHOD path_name.
DATA: lv_host TYPE string ##NEEDED.
FIND REGEX '(.*://[^/]*)(.*)' IN iv_url
SUBMATCHES lv_host rv_path_name.
ENDMETHOD.
METHOD regex.
FIND REGEX '(.*://[^/]*)(.*/)([^\.]*)[\.git]?' IN iv_url
SUBMATCHES ev_host ev_path ev_name.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Malformed URL' ).
ENDIF.
ENDMETHOD.
METHOD validate.
regex( iv_url ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_TIME IMPLEMENTATION.
METHOD get.
DATA: lv_i TYPE i,
lv_tz TYPE tznzone,
lv_utcdiff TYPE tznutcdiff,
lv_utcsign TYPE tznutcsign.
lv_i = sy-datum - c_epoch.
lv_i = lv_i * 86400.
lv_i = lv_i + sy-uzeit.
CALL FUNCTION 'TZON_GET_OS_TIMEZONE'
IMPORTING
ef_timezone = lv_tz.
CALL FUNCTION 'TZON_GET_OFFSET'
EXPORTING
if_timezone = lv_tz
if_local_date = sy-datum
if_local_time = sy-uzeit
IMPORTING
ef_utcdiff = lv_utcdiff
ef_utcsign = lv_utcsign
EXCEPTIONS
conversion_error = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Timezone error' ).
ENDIF.
CASE lv_utcsign.
WHEN '+'.
lv_i = lv_i - lv_utcdiff.
WHEN '-'.
lv_i = lv_i + lv_utcdiff.
ENDCASE.
rv_time = lv_i.
CONDENSE rv_time.
rv_time+11 = lv_utcsign.
rv_time+12 = lv_utcdiff.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_STATE IMPLEMENTATION.
METHOD reduce.
IF cv_prev = iv_cur OR iv_cur IS INITIAL.
RETURN. " No change
ELSEIF cv_prev IS INITIAL.
cv_prev = iv_cur.
ELSE.
cv_prev = zif_abapgit_definitions=>c_state-mixed.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_REQUIREMENT_HELPER IMPLEMENTATION.
METHOD get_requirement_met_status.
DATA: lt_installed TYPE STANDARD TABLE OF cvers_sdu.
FIELD-SYMBOLS: <ls_requirement> TYPE zif_abapgit_dot_abapgit=>ty_requirement,
<ls_status> TYPE ty_requirement_status,
<ls_installed_comp> TYPE cvers_sdu.
CALL FUNCTION 'DELIVERY_GET_INSTALLED_COMPS'
TABLES
tt_comptab = lt_installed
EXCEPTIONS
no_release_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from DELIVERY_GET_INSTALLED_COMPS { sy-subrc }| ) ##no_text.
ENDIF.
LOOP AT it_requirements ASSIGNING <ls_requirement>.
APPEND INITIAL LINE TO rt_status ASSIGNING <ls_status>.
<ls_status>-component = <ls_requirement>-component.
<ls_status>-required_release = <ls_requirement>-min_release.
<ls_status>-required_patch = <ls_requirement>-min_patch.
READ TABLE lt_installed WITH KEY component = <ls_requirement>-component
ASSIGNING <ls_installed_comp>.
IF sy-subrc = 0.
" Component is installed, requirement is met if the installed version is greater or equal
" to the required one.
<ls_status>-installed_release = <ls_installed_comp>-release.
<ls_status>-installed_patch = <ls_installed_comp>-extrelease.
<ls_status>-description = <ls_installed_comp>-desc_text.
<ls_status>-met = version_greater_or_equal( <ls_status> ).
ELSE.
" Component is not installed at all
<ls_status>-met = abap_false.
ENDIF.
UNASSIGN <ls_installed_comp>.
ENDLOOP.
ENDMETHOD.
METHOD is_requirements_met.
DATA: lt_met_status TYPE ty_requirement_status_tt.
lt_met_status = get_requirement_met_status( it_requirements ).
READ TABLE lt_met_status TRANSPORTING NO FIELDS WITH KEY met = abap_false.
IF sy-subrc = 0.
rv_status = 'N'.
ELSE.
rv_status = 'Y'.
ENDIF.
ENDMETHOD.
METHOD requirements_popup.
DATA: lt_met_status TYPE ty_requirement_status_tt,
lv_answer TYPE c LENGTH 1.
lt_met_status = get_requirement_met_status( it_requirements ).
show_requirement_popup( lt_met_status ).
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
text_question = 'The project has unmet requirements. Do you want to continue?'
IMPORTING
answer = lv_answer.
IF lv_answer <> '1'.
zcx_abapgit_exception=>raise( 'Cancelling because of unmet requirements.' ).
ENDIF.
ENDMETHOD.
METHOD show_requirement_popup.
TYPES: BEGIN OF lty_color_line,
color TYPE lvc_t_scol.
INCLUDE TYPE ty_requirement_status.
TYPES: END OF lty_color_line,
lty_color_tab TYPE STANDARD TABLE OF lty_color_line WITH DEFAULT KEY.
DATA: lo_alv TYPE REF TO cl_salv_table,
lo_column TYPE REF TO cl_salv_column,
lo_columns TYPE REF TO cl_salv_columns_table,
lt_color_table TYPE lty_color_tab,
lt_color_negative TYPE lvc_t_scol,
lt_color_positive TYPE lvc_t_scol,
ls_color TYPE lvc_s_scol,
lx_ex TYPE REF TO cx_root.
FIELD-SYMBOLS: <ls_line> TYPE lty_color_line,
<ls_requirement> LIKE LINE OF it_requirements.
ls_color-color-col = col_negative.
APPEND ls_color TO lt_color_negative.
ls_color-color-col = col_positive.
APPEND ls_color TO lt_color_positive.
CLEAR ls_color.
LOOP AT it_requirements ASSIGNING <ls_requirement>.
APPEND INITIAL LINE TO lt_color_table ASSIGNING <ls_line>.
MOVE-CORRESPONDING <ls_requirement> TO <ls_line>.
ENDLOOP.
LOOP AT lt_color_table ASSIGNING <ls_line>.
IF <ls_line>-met = abap_false.
<ls_line>-color = lt_color_negative.
ELSE.
<ls_line>-color = lt_color_positive.
ENDIF.
ENDLOOP.
UNASSIGN <ls_line>.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = lo_alv
CHANGING t_table = lt_color_table ).
lo_columns = lo_alv->get_columns( ).
lo_columns->get_column( 'MET' )->set_short_text( 'Met' ).
lo_columns->set_color_column( 'COLOR' ).
lo_columns->set_optimize( ).
lo_column = lo_columns->get_column( 'REQUIRED_RELEASE' ).
lo_column->set_short_text( 'Req. Rel.' ).
lo_column = lo_columns->get_column( 'REQUIRED_PATCH' ).
lo_column->set_short_text( 'Req. SP L.' ).
lo_alv->set_screen_popup( start_column = 30
end_column = 100
start_line = 10
end_line = 20 ).
lo_alv->get_display_settings( )->set_list_header( 'Requirements' ).
lo_alv->display( ).
CATCH cx_salv_msg cx_salv_not_found cx_salv_data_error INTO lx_ex.
zcx_abapgit_exception=>raise( lx_ex->get_text( ) ).
ENDTRY.
ENDMETHOD.
METHOD version_greater_or_equal.
DATA: lv_number TYPE numc4 ##NEEDED.
TRY.
MOVE EXACT: is_status-installed_release TO lv_number,
is_status-installed_patch TO lv_number,
is_status-required_release TO lv_number,
is_status-required_patch TO lv_number.
CATCH cx_sy_conversion_error.
" Cannot compare by number, assume requirement not fullfilled (user can force install
" anyways if this was an error)
rv_true = abap_false.
RETURN.
ENDTRY.
" Versions are comparable by number, compare release and if necessary patch level
IF is_status-installed_release > is_status-required_release
OR ( is_status-installed_release = is_status-required_release
AND ( is_status-required_patch IS INITIAL OR
is_status-installed_patch >= is_status-required_patch ) ).
rv_true = abap_true.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PROGRESS IMPLEMENTATION.
METHOD calc_pct.
DATA: lv_f TYPE f.
lv_f = ( iv_current / mv_total ) * 100.
rv_pct = lv_f.
IF rv_pct = 100.
rv_pct = 99.
ENDIF.
ENDMETHOD.
METHOD constructor.
mv_total = iv_total.
ENDMETHOD.
METHOD show.
DATA: lv_pct TYPE i.
DATA: lv_time TYPE t.
CONSTANTS: c_wait_secs TYPE i VALUE 2.
GET TIME.
lv_time = sy-uzeit.
IF mv_cv_time_next IS INITIAL AND mv_cv_datum_next IS INITIAL.
mv_cv_time_next = lv_time.
mv_cv_datum_next = sy-datum.
ENDIF.
"We only do a progress indication if enough time has passed
IF lv_time >= mv_cv_time_next AND sy-datum = mv_cv_datum_next OR
sy-datum > mv_cv_datum_next.
lv_pct = calc_pct( iv_current ).
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
percentage = lv_pct
text = iv_text.
mv_cv_time_next = lv_time + c_wait_secs.
ENDIF.
IF sy-datum > mv_cv_datum_next.
mv_cv_datum_next = sy-datum.
ENDIF.
IF mv_cv_time_next < lv_time.
mv_cv_datum_next = sy-datum + 1.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PATH IMPLEMENTATION.
METHOD change_dir.
DATA: lv_last TYPE i,
lv_temp TYPE string.
lv_last = strlen( iv_cur_dir ) - 1.
IF iv_cd = '' OR iv_cd = '.'. " No change
rv_path = iv_cur_dir.
ELSEIF iv_cd+0(1) = '/'. " Absolute path
rv_path = iv_cd.
ELSEIF iv_cd = '..'. " CD back
IF iv_cur_dir = '/' OR iv_cur_dir = ''. " Back from root = root
rv_path = iv_cur_dir.
ELSE.
lv_temp = reverse( iv_cur_dir ).
IF lv_temp+0(1) = '/'.
SHIFT lv_temp BY 1 PLACES LEFT.
ENDIF.
SHIFT lv_temp UP TO '/' LEFT.
rv_path = reverse( lv_temp ).
ENDIF.
ELSEIF iv_cur_dir+lv_last(1) = '/'. " Append cd to cur_dir separated by /
rv_path = iv_cur_dir && iv_cd.
ELSE.
rv_path = iv_cur_dir && '/' && iv_cd.
ENDIF.
" TODO: improve logic and cases
ENDMETHOD.
METHOD get_filename_from_syspath.
DATA: lv_split TYPE c LENGTH 1,
lv_index TYPE i,
lt_split TYPE TABLE OF string.
" filename | c:\filename | /dir/filename | \\server\filename
IF iv_path CA '/'.
lv_split = '/'.
ELSE.
lv_split = '\'.
ENDIF.
SPLIT iv_path AT lv_split INTO TABLE lt_split.
lv_index = lines( lt_split ).
READ TABLE lt_split INDEX lv_index INTO rv_filename.
ENDMETHOD.
METHOD is_root.
rv_yes = boolc( iv_path = '/' ).
ENDMETHOD.
METHOD is_subdir.
DATA lv_len TYPE i.
DATA lv_last TYPE i.
lv_len = strlen( iv_parent ).
lv_last = lv_len - 1.
rv_yes = boolc( strlen( iv_path ) > lv_len
AND iv_path+0(lv_len) = iv_parent
AND ( iv_parent+lv_last(1) = '/' OR iv_path+lv_len(1) = '/' ) ).
ENDMETHOD.
METHOD split_file_location.
DATA: lv_cnt TYPE i,
lv_len TYPE i.
FIND FIRST OCCURRENCE OF REGEX '^/(.*/)?' IN iv_fullpath
MATCH COUNT lv_cnt
MATCH LENGTH lv_len.
IF lv_cnt > 0.
ev_path = iv_fullpath+0(lv_len).
ev_filename = iv_fullpath+lv_len.
ELSE.
CLEAR ev_path.
ev_filename = iv_fullpath.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_LOGIN_MANAGER IMPLEMENTATION.
METHOD append.
FIELD-SYMBOLS: <ls_auth> LIKE LINE OF gt_auth.
READ TABLE gt_auth WITH KEY uri = zcl_abapgit_url=>host( iv_uri )
TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
APPEND INITIAL LINE TO gt_auth ASSIGNING <ls_auth>.
<ls_auth>-uri = zcl_abapgit_url=>host( iv_uri ).
<ls_auth>-authorization = iv_auth.
ENDIF.
ENDMETHOD.
METHOD clear.
CLEAR gt_auth.
ENDMETHOD.
METHOD load.
DATA: ls_auth LIKE LINE OF gt_auth.
READ TABLE gt_auth INTO ls_auth WITH KEY uri = zcl_abapgit_url=>host( iv_uri ).
IF sy-subrc = 0.
rv_authorization = ls_auth-authorization.
IF NOT ii_client IS INITIAL.
ii_client->request->set_header_field(
name = 'authorization'
value = ls_auth-authorization ). "#EC NOTEXT
ii_client->propertytype_logon_popup = ii_client->co_disabled.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD save.
DATA: lv_auth TYPE string.
lv_auth = ii_client->request->get_header_field( 'authorization' ). "#EC NOTEXT
IF NOT lv_auth IS INITIAL.
append( iv_uri = iv_uri
iv_auth = lv_auth ).
ENDIF.
ENDMETHOD.
METHOD set.
DATA: lv_concat TYPE string.
ASSERT NOT iv_uri IS INITIAL.
IF iv_username IS INITIAL OR iv_password IS INITIAL.
RETURN.
ENDIF.
CONCATENATE iv_username ':' iv_password INTO lv_concat.
rv_auth = cl_http_utility=>if_http_utility~encode_base64( lv_concat ).
CONCATENATE 'Basic' rv_auth INTO rv_auth
SEPARATED BY space ##NO_TEXT.
append( iv_uri = iv_uri
iv_auth = rv_auth ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_log IMPLEMENTATION.
METHOD add.
FIELD-SYMBOLS: <ls_log> LIKE LINE OF mt_log.
APPEND INITIAL LINE TO mt_log ASSIGNING <ls_log>.
<ls_log>-msg = iv_msg.
<ls_log>-type = iv_type.
<ls_log>-rc = iv_rc.
ENDMETHOD.
METHOD add_error.
add( iv_msg = iv_msg
iv_type = 'E' ).
ENDMETHOD.
METHOD add_info.
add( iv_msg = iv_msg
iv_type = 'I' ).
ENDMETHOD.
METHOD add_warning.
add( iv_msg = iv_msg
iv_type = 'W' ).
ENDMETHOD.
METHOD clear.
CLEAR mt_log.
ENDMETHOD.
METHOD count.
rv_count = lines( mt_log ).
ENDMETHOD.
METHOD has_rc.
READ TABLE mt_log WITH KEY rc = iv_rc TRANSPORTING NO FIELDS.
rv_yes = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD prepare_log_for_display.
DATA: ls_log TYPE ty_log_out.
FIELD-SYMBOLS: <ls_log> TYPE ty_log.
LOOP AT mt_log ASSIGNING <ls_log>.
CLEAR: ls_log.
ls_log-msg = <ls_log>-msg.
CASE <ls_log>-type.
WHEN 'E' OR 'A' OR 'X'.
ls_log-type = icon_led_red.
WHEN 'W'.
ls_log-type = icon_led_yellow.
WHEN 'I' OR 'S'.
ls_log-type = icon_led_green.
WHEN OTHERS.
ls_log-type = icon_led_inactive.
ENDCASE.
INSERT ls_log INTO TABLE rt_log_out.
ENDLOOP.
ENDMETHOD.
METHOD show.
DATA: lt_log TYPE tty_log_out,
lo_alv TYPE REF TO cl_salv_table,
lx_error TYPE REF TO cx_salv_error,
lo_form_header TYPE REF TO cl_salv_form_header_info,
lo_columns TYPE REF TO cl_salv_columns_table,
lo_column TYPE REF TO cl_salv_column,
lo_functions TYPE REF TO cl_salv_functions_list.
lt_log = prepare_log_for_display( ).
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = lt_log ).
lo_functions = lo_alv->get_functions( ).
lo_functions->set_all( ).
lo_columns = lo_alv->get_columns( ).
lo_columns->set_optimize( ).
lo_column = lo_columns->get_column( |TYPE| ).
lo_column->set_medium_text( |Type| ).
lo_column = lo_columns->get_column( |MSG| ).
lo_column->set_medium_text( |Message| ).
lo_alv->set_screen_popup( start_column = 10
end_column = 120
start_line = 4
end_line = 20 ).
CREATE OBJECT lo_form_header
EXPORTING
text = iv_header_text.
lo_alv->set_top_of_list( lo_form_header ).
lo_alv->display( ).
CATCH cx_salv_error INTO lx_error.
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
METHOD to_html.
DATA: lv_class TYPE string,
lv_icon TYPE string.
FIELD-SYMBOLS: <ls_log> LIKE LINE OF mt_log.
CREATE OBJECT ro_html.
IF count( ) = 0.
RETURN.
ENDIF.
LOOP AT mt_log ASSIGNING <ls_log>.
CASE <ls_log>-type.
WHEN 'W'.
lv_icon = 'alert'.
lv_class = 'warning'.
WHEN 'E'.
lv_icon = 'flame'.
lv_class = 'error'.
WHEN OTHERS. " ??? unexpected
lv_icon = 'flame'.
lv_class = 'error'.
ENDCASE.
ro_html->add( |<span class="{ lv_class }">| ).
ro_html->add_icon( lv_icon ).
ro_html->add( <ls_log>-msg ).
ro_html->add( '</span>' ).
ENDLOOP.
ENDMETHOD.
METHOD write.
DATA: ls_log LIKE LINE OF mt_log,
lv_text TYPE string.
LOOP AT mt_log INTO ls_log.
lv_text = |{ ls_log-type }: { ls_log-msg }|.
WRITE: / lv_text.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_LANGUAGE IMPLEMENTATION.
METHOD class_constructor.
DATA lv_dummy TYPE string.
GET LOCALE LANGUAGE gv_login_language COUNTRY lv_dummy MODIFIER lv_dummy.
ENDMETHOD.
METHOD restore_login_language.
SET LOCALE LANGUAGE gv_login_language.
ENDMETHOD.
METHOD set_current_language.
SET LOCALE LANGUAGE iv_language.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_HASH IMPLEMENTATION.
METHOD adler32.
CONSTANTS: lc_adler TYPE i VALUE 65521,
lc_max_b TYPE i VALUE 1800000000.
DATA: lv_index TYPE i,
lv_a TYPE i VALUE 1,
lv_b TYPE i VALUE 0,
lv_x TYPE x LENGTH 2,
lv_ca TYPE c LENGTH 4,
lv_cb TYPE c LENGTH 4,
lv_char8 TYPE c LENGTH 8.
DO xstrlen( iv_xstring ) TIMES.
lv_index = sy-index - 1.
lv_a = lv_a + iv_xstring+lv_index(1).
lv_b = lv_b + lv_a.
IF lv_b > lc_max_b.
lv_a = lv_a MOD lc_adler.
lv_b = lv_b MOD lc_adler.
ENDIF.
ENDDO.
lv_a = lv_a MOD lc_adler.
lv_b = lv_b MOD lc_adler.
lv_x = lv_a.
lv_ca = lv_x.
lv_x = lv_b.
lv_cb = lv_x.
CONCATENATE lv_cb lv_ca INTO lv_char8.
rv_checksum = lv_char8.
ENDMETHOD.
METHOD sha1.
DATA: lv_len TYPE i,
lv_char10 TYPE c LENGTH 10,
lv_string TYPE string,
lv_xstring TYPE xstring.
lv_len = xstrlen( iv_data ).
lv_char10 = lv_len.
CONDENSE lv_char10.
CONCATENATE iv_type lv_char10 INTO lv_string SEPARATED BY space.
lv_xstring = zcl_abapgit_convert=>string_to_xstring_utf8( lv_string ).
lv_string = lv_xstring.
CONCATENATE lv_string '00' INTO lv_string.
lv_xstring = lv_string.
CONCATENATE lv_xstring iv_data INTO lv_xstring IN BYTE MODE.
rv_sha1 = sha1_raw( lv_xstring ).
ENDMETHOD.
METHOD sha1_raw.
DATA: lv_hash TYPE hash160.
CALL FUNCTION 'CALCULATE_HASH_FOR_RAW'
EXPORTING
data = iv_data
IMPORTING
hash = lv_hash
EXCEPTIONS
unknown_alg = 1
param_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error while calculating SHA1' ).
ENDIF.
rv_sha1 = lv_hash.
TRANSLATE rv_sha1 TO LOWER CASE.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_DIFF IMPLEMENTATION.
METHOD calculate_line_num_and_stats.
DATA: lv_new TYPE i VALUE 1,
lv_old TYPE i VALUE 1.
FIELD-SYMBOLS: <ls_diff> LIKE LINE OF mt_diff.
LOOP AT mt_diff ASSIGNING <ls_diff>.
<ls_diff>-new_num = lv_new.
<ls_diff>-old_num = lv_old.
CASE <ls_diff>-result. " Line nums
WHEN zif_abapgit_definitions=>c_diff-delete.
lv_old = lv_old + 1.
CLEAR <ls_diff>-new_num.
WHEN zif_abapgit_definitions=>c_diff-insert.
lv_new = lv_new + 1.
CLEAR <ls_diff>-old_num.
WHEN OTHERS.
lv_new = lv_new + 1.
lv_old = lv_old + 1.
ENDCASE.
CASE <ls_diff>-result. " Stats
WHEN zif_abapgit_definitions=>c_diff-insert.
ms_stats-insert = ms_stats-insert + 1.
WHEN zif_abapgit_definitions=>c_diff-delete.
ms_stats-delete = ms_stats-delete + 1.
WHEN zif_abapgit_definitions=>c_diff-update.
ms_stats-update = ms_stats-update + 1.
ENDCASE.
ENDLOOP.
ENDMETHOD.
METHOD compute.
DATA: lt_trdirtab_old TYPE TABLE OF trdir,
lt_trdirtab_new TYPE TABLE OF trdir,
lt_trdir_delta TYPE TABLE OF xtrdir.
CALL FUNCTION 'SVRS_COMPUTE_DELTA_REPS'
TABLES
texttab_old = it_old
texttab_new = it_new
trdirtab_old = lt_trdirtab_old
trdirtab_new = lt_trdirtab_new
trdir_delta = lt_trdir_delta
text_delta = rt_delta.
ENDMETHOD.
METHOD constructor.
DATA: lt_delta TYPE vxabapt255_tab,
lt_new TYPE abaptxt255_tab,
lt_old TYPE abaptxt255_tab.
unpack( EXPORTING iv_new = iv_new
iv_old = iv_old
IMPORTING et_new = lt_new
et_old = lt_old ).
lt_delta = compute( it_new = lt_new
it_old = lt_old ).
mt_diff = render( it_new = lt_new
it_old = lt_old
it_delta = lt_delta ).
calculate_line_num_and_stats( ).
map_beacons( ).
shortlist( ).
ENDMETHOD.
METHOD get.
rt_diff = mt_diff.
ENDMETHOD.
METHOD map_beacons.
DEFINE _add_regex.
CREATE OBJECT lo_regex
EXPORTING pattern = &1
ignore_case = abap_true ##NO_TEXT.
APPEND lo_regex TO lt_regex_set.
END-OF-DEFINITION.
DATA: lv_beacon_idx TYPE i,
lv_offs TYPE i,
lv_beacon_str TYPE string,
lv_beacon_2lev TYPE string,
lv_submatch TYPE string,
lo_regex TYPE REF TO cl_abap_regex,
lt_regex_set TYPE TABLE OF REF TO cl_abap_regex.
FIELD-SYMBOLS: <ls_diff> LIKE LINE OF mt_diff.
_add_regex '^\s*(CLASS|FORM|MODULE|REPORT|METHOD)\s'.
_add_regex '^\s*START-OF-'.
_add_regex '^\s*INITIALIZATION(\s|\.)'.
LOOP AT mt_diff ASSIGNING <ls_diff>.
CLEAR lv_offs.
<ls_diff>-beacon = lv_beacon_idx.
LOOP AT lt_regex_set INTO lo_regex. "
FIND FIRST OCCURRENCE OF REGEX lo_regex IN <ls_diff>-new SUBMATCHES lv_submatch.
IF sy-subrc = 0. " Match
lv_beacon_str = <ls_diff>-new.
lv_submatch = to_upper( lv_submatch ).
" Get rid of comments and end of line
FIND FIRST OCCURRENCE OF '.' IN lv_beacon_str MATCH OFFSET lv_offs.
IF sy-subrc <> 0.
FIND FIRST OCCURRENCE OF '"' IN lv_beacon_str MATCH OFFSET lv_offs.
ENDIF.
IF lv_offs > 0.
lv_beacon_str = lv_beacon_str(lv_offs).
ENDIF.
IF lv_submatch = 'CLASS'.
lv_beacon_2lev = lv_beacon_str.
ELSEIF lv_submatch = 'METHOD'.
lv_beacon_str = lv_beacon_2lev && ` => ` && lv_beacon_str.
ENDIF.
APPEND lv_beacon_str TO mt_beacons.
lv_beacon_idx = sy-tabix.
<ls_diff>-beacon = lv_beacon_idx.
EXIT. "Loop
ENDIF.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
METHOD render.
DEFINE _append.
CLEAR ls_diff.
ls_diff-new = &1.
ls_diff-result = &2.
ls_diff-old = &3.
APPEND ls_diff TO rt_diff.
END-OF-DEFINITION.
DATA: lv_oindex TYPE i VALUE 1,
lv_nindex TYPE i VALUE 1,
ls_new LIKE LINE OF it_new,
ls_old LIKE LINE OF it_old,
ls_diff LIKE LINE OF rt_diff,
lt_delta LIKE it_delta,
ls_delta LIKE LINE OF it_delta.
lt_delta = it_delta.
DO.
READ TABLE lt_delta INTO ls_delta WITH KEY number = lv_oindex.
IF sy-subrc = 0.
DELETE lt_delta INDEX sy-tabix.
CASE ls_delta-vrsflag.
WHEN zif_abapgit_definitions=>c_diff-delete.
_append '' zif_abapgit_definitions=>c_diff-delete ls_delta-line.
lv_oindex = lv_oindex + 1.
WHEN zif_abapgit_definitions=>c_diff-insert.
_append ls_delta-line zif_abapgit_definitions=>c_diff-insert ''.
lv_nindex = lv_nindex + 1.
WHEN zif_abapgit_definitions=>c_diff-update.
CLEAR ls_new.
READ TABLE it_new INTO ls_new INDEX lv_nindex.
ASSERT sy-subrc = 0.
_append ls_new zif_abapgit_definitions=>c_diff-update ls_delta-line.
lv_nindex = lv_nindex + 1.
lv_oindex = lv_oindex + 1.
WHEN OTHERS.
ASSERT 0 = 1.
ENDCASE.
ELSE.
CLEAR ls_new.
READ TABLE it_new INTO ls_new INDEX lv_nindex. "#EC CI_SUBRC
lv_nindex = lv_nindex + 1.
CLEAR ls_old.
READ TABLE it_old INTO ls_old INDEX lv_oindex. "#EC CI_SUBRC
lv_oindex = lv_oindex + 1.
_append ls_new '' ls_old.
ENDIF.
IF lv_nindex > lines( it_new ) AND lv_oindex > lines( it_old ).
EXIT. " current loop
ENDIF.
ENDDO.
ENDMETHOD.
METHOD shortlist.
DATA: lv_index TYPE i.
FIELD-SYMBOLS: <ls_diff> LIKE LINE OF mt_diff.
IF lines( mt_diff ) < 20.
LOOP AT mt_diff ASSIGNING <ls_diff>.
<ls_diff>-short = abap_true.
ENDLOOP.
ELSE.
LOOP AT mt_diff TRANSPORTING NO FIELDS
WHERE NOT result IS INITIAL AND short = abap_false.
lv_index = sy-tabix.
DO 8 TIMES. " Backward
READ TABLE mt_diff INDEX ( lv_index - sy-index ) ASSIGNING <ls_diff>.
IF sy-subrc <> 0 OR <ls_diff>-short = abap_true. " tab bound or prev marker
EXIT.
ENDIF.
<ls_diff>-short = abap_true.
ENDDO.
DO 8 TIMES. " Forward
READ TABLE mt_diff INDEX ( lv_index + sy-index - 1 ) ASSIGNING <ls_diff>.
IF sy-subrc <> 0. " tab bound reached
EXIT.
ENDIF.
CHECK <ls_diff>-short = abap_false. " skip marked
<ls_diff>-short = abap_true.
ENDDO.
ENDLOOP.
ENDIF.
ENDMETHOD.
METHOD stats.
rs_count = ms_stats.
ENDMETHOD.
METHOD unpack.
DATA: lv_new TYPE string,
lv_old TYPE string.
lv_new = zcl_abapgit_convert=>xstring_to_string_utf8( iv_new ).
lv_old = zcl_abapgit_convert=>xstring_to_string_utf8( iv_old ).
SPLIT lv_new AT zif_abapgit_definitions=>c_newline INTO TABLE et_new.
SPLIT lv_old AT zif_abapgit_definitions=>c_newline INTO TABLE et_old.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_CONVERT IMPLEMENTATION.
METHOD bitbyte_to_int.
DATA: bitbyte TYPE string,
len TYPE i,
offset TYPE i.
bitbyte = iv_bits.
SHIFT bitbyte LEFT DELETING LEADING '0 '.
len = strlen( bitbyte ).
offset = len - 1.
rv_int = 0.
DO len TIMES.
IF sy-index = 1.
"Intialize
CASE bitbyte+offset(1).
WHEN '1'.
rv_int = 1.
ENDCASE.
ELSE.
CASE bitbyte+offset(1).
WHEN '1'.
rv_int = rv_int + ( 2 ** ( sy-index - 1 ) ).
ENDCASE.
ENDIF.
offset = offset - 1. "Move Cursor
ENDDO.
ENDMETHOD.
METHOD int_to_xstring4.
DATA: lv_x TYPE x LENGTH 4.
lv_x = iv_i.
rv_xstring = lv_x.
ENDMETHOD.
METHOD split_string.
FIND FIRST OCCURRENCE OF cl_abap_char_utilities=>cr_lf IN iv_string.
" Convert string into table depending on separator type CR_LF vs. LF
IF sy-subrc = 0.
SPLIT iv_string AT cl_abap_char_utilities=>cr_lf INTO TABLE rt_lines.
ELSE.
SPLIT iv_string AT cl_abap_char_utilities=>newline INTO TABLE rt_lines.
ENDIF.
ENDMETHOD.
METHOD string_to_xstring_utf8.
DATA: lo_obj TYPE REF TO cl_abap_conv_out_ce.
TRY.
lo_obj = cl_abap_conv_out_ce=>create( encoding = 'UTF-8' ).
lo_obj->convert( EXPORTING data = iv_string
IMPORTING buffer = rv_xstring ).
CATCH cx_parameter_invalid_range
cx_sy_codepage_converter_init
cx_sy_conversion_codepage
cx_parameter_invalid_type. "#EC NO_HANDLER
ENDTRY.
ENDMETHOD.
METHOD xstring_to_int.
DATA: lv_xstring TYPE xstring,
lv_x TYPE x.
lv_xstring = iv_xstring.
WHILE xstrlen( lv_xstring ) > 0.
lv_x = lv_xstring(1).
rv_i = rv_i * 256 + lv_x.
lv_xstring = lv_xstring+1.
ENDWHILE.
ENDMETHOD.
METHOD xstring_to_string_utf8.
DATA: lv_len TYPE i,
lo_obj TYPE REF TO cl_abap_conv_in_ce.
TRY.
lo_obj = cl_abap_conv_in_ce=>create(
input = iv_data
encoding = 'UTF-8' ).
lv_len = xstrlen( iv_data ).
lo_obj->read( EXPORTING n = lv_len
IMPORTING data = rv_string ).
CATCH cx_parameter_invalid_range
cx_sy_codepage_converter_init
cx_sy_conversion_codepage
cx_parameter_invalid_type. "#EC NO_HANDLER
ENDTRY.
ENDMETHOD.
METHOD x_to_bitbyte.
CLEAR rv_bitbyte.
GET BIT 1 OF iv_x INTO rv_bitbyte+0(1).
GET BIT 2 OF iv_x INTO rv_bitbyte+1(1).
GET BIT 3 OF iv_x INTO rv_bitbyte+2(1).
GET BIT 4 OF iv_x INTO rv_bitbyte+3(1).
GET BIT 5 OF iv_x INTO rv_bitbyte+4(1).
GET BIT 6 OF iv_x INTO rv_bitbyte+5(1).
GET BIT 7 OF iv_x INTO rv_bitbyte+6(1).
GET BIT 8 OF iv_x INTO rv_bitbyte+7(1).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ui_injector IMPLEMENTATION.
METHOD set_popups.
zcl_abapgit_ui_factory=>mi_popups = ii_popups.
ENDMETHOD.
METHOD set_tag_popups.
zcl_abapgit_ui_factory=>mi_tag_popups = ii_tag_popups.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ui_factory IMPLEMENTATION.
METHOD get_popups.
IF mi_popups IS INITIAL.
CREATE OBJECT mi_popups TYPE zcl_abapgit_popups.
ENDIF.
ri_popups = mi_popups.
ENDMETHOD.
METHOD get_tag_popups.
IF mi_tag_popups IS INITIAL.
CREATE OBJECT mi_tag_popups TYPE zcl_abapgit_tag_popups.
ENDIF.
ri_tag_popups = mi_tag_popups.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_tag_popups IMPLEMENTATION.
METHOD clean_up.
IF mo_text_control IS BOUND.
mo_text_control->finalize( ).
mo_text_control->free(
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
OTHERS = 3 ).
ASSERT sy-subrc = 0.
CLEAR: mo_text_control.
ENDIF.
IF mo_docking_container IS BOUND.
mo_docking_container->finalize( ).
mo_docking_container->free(
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
OTHERS = 3 ).
ASSERT sy-subrc = 0.
CLEAR: mo_docking_container.
ENDIF.
ENDMETHOD.
METHOD on_double_click.
FIELD-SYMBOLS: <ls_tag> TYPE zcl_abapgit_tag_popups=>ty_tag_out.
READ TABLE mt_tags ASSIGNING <ls_tag>
INDEX row.
IF sy-subrc <> 0 OR <ls_tag>-body IS INITIAL.
RETURN.
ENDIF.
show_docking_container_with( <ls_tag>-body ).
ENDMETHOD.
METHOD prepare_tags_for_display.
DATA: ls_tag_out LIKE LINE OF rt_tags_out.
FIELD-SYMBOLS: <ls_tag> TYPE zif_abapgit_definitions=>ty_git_tag.
LOOP AT it_tags ASSIGNING <ls_tag>.
CLEAR: ls_tag_out.
MOVE-CORRESPONDING <ls_tag> TO ls_tag_out.
ls_tag_out-name = zcl_abapgit_tag=>remove_tag_prefix( ls_tag_out-name ).
IF ls_tag_out-body IS NOT INITIAL.
ls_tag_out-body_icon = |{ icon_display_text }|.
ENDIF.
INSERT ls_tag_out INTO TABLE rt_tags_out.
ENDLOOP.
ENDMETHOD.
METHOD show_docking_container_with.
IF mo_docking_container IS NOT BOUND.
CREATE OBJECT mo_docking_container
EXPORTING
side = cl_gui_docking_container=>dock_at_bottom
extension = 120
EXCEPTIONS
cntl_error = 1
cntl_system_error = 2
create_error = 3
lifetime_error = 4
lifetime_dynpro_dynpro_link = 5
OTHERS = 6.
ASSERT sy-subrc = 0.
ENDIF.
IF mo_text_control IS NOT BOUND.
CREATE OBJECT mo_text_control
EXPORTING
parent = mo_docking_container
EXCEPTIONS
error_cntl_create = 1
error_cntl_init = 2
error_cntl_link = 3
error_dp_create = 4
gui_type_not_supported = 5
OTHERS = 6.
ASSERT sy-subrc = 0.
mo_text_control->set_readonly_mode(
EXCEPTIONS
error_cntl_call_method = 1
invalid_parameter = 2
OTHERS = 3 ).
ASSERT sy-subrc = 0.
ENDIF.
mo_text_control->set_textstream(
EXPORTING
text = iv_text
EXCEPTIONS
error_cntl_call_method = 1
not_supported_by_gui = 2
OTHERS = 3 ).
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD zif_abapgit_tag_popups~tag_list_popup.
DATA: lo_alv TYPE REF TO cl_salv_table,
lo_table_header TYPE REF TO cl_salv_form_header_info,
lo_columns TYPE REF TO cl_salv_columns_table,
lx_alv TYPE REF TO cx_salv_error,
lt_tags TYPE zif_abapgit_definitions=>ty_git_tag_list_tt,
lo_event TYPE REF TO cl_salv_events_table.
CLEAR: mt_tags.
lt_tags = zcl_abapgit_factory=>get_branch_overview( io_repo = io_repo )->get_tags( ).
IF lines( lt_tags ) = 0.
zcx_abapgit_exception=>raise( `There are no tags for this repository` ).
ENDIF.
mt_tags = prepare_tags_for_display( lt_tags ).
TRY.
cl_salv_table=>factory(
IMPORTING
r_salv_table = lo_alv
CHANGING
t_table = mt_tags ).
lo_columns = lo_alv->get_columns( ).
lo_columns->get_column( `TYPE` )->set_technical( ).
lo_columns->get_column( `DISPLAY_NAME` )->set_technical( ).
lo_columns->get_column( `BODY` )->set_technical( ).
lo_columns->get_column( `NAME` )->set_medium_text( 'Tag name' ).
lo_columns->set_column_position( columnname = 'NAME'
position = 1 ).
lo_columns->get_column( `TAGGER_NAME` )->set_medium_text( 'Tagger' ).
lo_columns->set_column_position( columnname = 'TAGGER_NAME'
position = 2 ).
lo_columns->get_column( `TAGGER_EMAIL` )->set_medium_text( 'Tagger E-Mail' ).
lo_columns->set_column_position( columnname = 'TAGGER_EMAIL'
position = 3 ).
lo_columns->get_column( `MESSAGE` )->set_medium_text( 'Tag message' ).
lo_columns->set_column_position( columnname = 'MESSAGE'
position = 4 ).
lo_columns->get_column( `BODY_ICON` )->set_medium_text( 'Body' ).
lo_columns->get_column( `BODY_ICON` )->set_output_length( 4 ).
lo_columns->set_column_position( columnname = 'BODY_ICON'
position = 5 ).
lo_columns->get_column( `SHA1` )->set_output_length( 15 ).
lo_columns->get_column( `SHA1` )->set_medium_text( 'SHA' ).
lo_columns->set_column_position( columnname = 'SHA1'
position = 6 ).
lo_columns->get_column( `OBJECT` )->set_output_length( 15 ).
lo_columns->get_column( `OBJECT` )->set_medium_text( 'Object' ).
lo_columns->set_column_position( columnname = 'OBJECT'
position = 7 ).
lo_columns->set_optimize( ).
lo_alv->set_screen_popup( start_column = 7
end_column = 200
start_line = 1
end_line = 25 ).
CREATE OBJECT lo_table_header
EXPORTING
text = `Tags`.
lo_alv->set_top_of_list( lo_table_header ).
lo_event = lo_alv->get_event( ).
SET HANDLER on_double_click FOR lo_event.
lo_alv->display( ).
CATCH cx_salv_error INTO lx_alv.
zcx_abapgit_exception=>raise( lx_alv->get_text( ) ).
ENDTRY.
clean_up( ).
ENDMETHOD.
METHOD zif_abapgit_tag_popups~tag_select_popup.
DATA: lt_tags TYPE zif_abapgit_definitions=>ty_git_tag_list_tt,
lv_answer TYPE c LENGTH 1,
lt_selection TYPE TABLE OF spopli,
lv_name_with_prefix TYPE string.
FIELD-SYMBOLS: <ls_sel> LIKE LINE OF lt_selection,
<ls_tag> LIKE LINE OF lt_tags.
lt_tags = zcl_abapgit_factory=>get_branch_overview( io_repo = io_repo )->get_tags( ).
IF lines( lt_tags ) = 0.
zcx_abapgit_exception=>raise( `There are no tags for this repository` ).
ENDIF.
LOOP AT lt_tags ASSIGNING <ls_tag>.
INSERT INITIAL LINE INTO lt_selection INDEX 1 ASSIGNING <ls_sel>.
<ls_sel>-varoption = zcl_abapgit_tag=>remove_tag_prefix( <ls_tag>-name ).
ENDLOOP.
CALL FUNCTION 'POPUP_TO_DECIDE_LIST'
EXPORTING
textline1 = 'Select tag'
titel = 'Select tag'
start_col = 30
start_row = 5
IMPORTING
answer = lv_answer
TABLES
t_spopli = lt_selection
EXCEPTIONS
not_enough_answers = 1
too_much_answers = 2
too_much_marks = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_TO_DECIDE_LIST' ).
ENDIF.
IF lv_answer = 'A'.
RETURN.
ENDIF.
READ TABLE lt_selection ASSIGNING <ls_sel> WITH KEY selflag = abap_true.
ASSERT sy-subrc = 0.
lv_name_with_prefix = zcl_abapgit_tag=>add_tag_prefix( <ls_sel>-varoption ).
READ TABLE lt_tags ASSIGNING <ls_tag> WITH KEY name = lv_name_with_prefix.
ASSERT sy-subrc = 0.
rs_tag = <ls_tag>.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_SERVICES_REPO IMPLEMENTATION.
METHOD gui_deserialize.
DATA: ls_checks TYPE zif_abapgit_definitions=>ty_deserialize_checks,
lt_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt.
ls_checks = io_repo->deserialize_checks( ).
TRY.
popup_overwrite( CHANGING ct_overwrite = ls_checks-overwrite ).
popup_package_overwrite( CHANGING ct_overwrite = ls_checks-warning_package ).
IF ls_checks-requirements-met = 'N'.
lt_requirements = io_repo->get_dot_abapgit( )->get_data( )-requirements.
zcl_abapgit_requirement_helper=>requirements_popup( lt_requirements ).
ls_checks-requirements-decision = 'Y'.
ENDIF.
IF ls_checks-transport-required = abap_true.
ls_checks-transport-transport = zcl_abapgit_ui_factory=>get_popups( )->popup_transport_request(
is_transport_type = ls_checks-transport-type ).
ENDIF.
CATCH zcx_abapgit_cancel.
RETURN.
ENDTRY.
io_repo->deserialize( ls_checks ).
ENDMETHOD.
METHOD new_offline.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo,
ls_popup TYPE zif_abapgit_popups=>ty_popup.
ls_popup = zcl_abapgit_ui_factory=>get_popups( )->repo_new_offline( ).
IF ls_popup-cancel = abap_true.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
lo_repo = zcl_abapgit_repo_srv=>get_instance( )->new_offline(
iv_url = ls_popup-url
iv_package = ls_popup-package ).
zcl_abapgit_persistence_user=>get_instance( )->set_repo_show( lo_repo->get_key( ) ). " Set default repo for user
toggle_favorite( lo_repo->get_key( ) ).
COMMIT WORK AND WAIT.
ENDMETHOD.
METHOD new_online.
DATA: ls_popup TYPE zif_abapgit_popups=>ty_popup.
ls_popup = zcl_abapgit_ui_factory=>get_popups( )->repo_popup( iv_url ).
IF ls_popup-cancel = abap_true.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
ro_repo = zcl_abapgit_repo_srv=>get_instance( )->new_online(
iv_url = ls_popup-url
iv_branch_name = ls_popup-branch_name
iv_package = ls_popup-package ).
toggle_favorite( ro_repo->get_key( ) ).
zcl_abapgit_persistence_user=>get_instance( )->set_repo_show( ro_repo->get_key( ) ).
COMMIT WORK.
ENDMETHOD.
METHOD open_se80.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
in_new_window = abap_true
object_name = iv_package
object_type = 'DEVC'
with_objectlist = abap_true.
ENDMETHOD.
METHOD popup_overwrite.
DATA: lt_columns TYPE stringtab,
lt_selected LIKE ct_overwrite,
lv_column LIKE LINE OF lt_columns,
li_popups TYPE REF TO zif_abapgit_popups.
FIELD-SYMBOLS: <ls_overwrite> LIKE LINE OF ct_overwrite.
IF lines( ct_overwrite ) = 0.
RETURN.
ENDIF.
lv_column = 'OBJ_TYPE'.
INSERT lv_column INTO TABLE lt_columns.
lv_column = 'OBJ_NAME'.
INSERT lv_column INTO TABLE lt_columns.
li_popups = zcl_abapgit_ui_factory=>get_popups( ).
li_popups->popup_to_select_from_list(
EXPORTING
it_list = ct_overwrite
iv_header_text = |The following Objects have been modified locally.|
&& | Select the Objects which should be overwritten.|
iv_select_column_text = 'Overwrite?'
it_columns_to_display = lt_columns
IMPORTING
et_list = lt_selected ).
LOOP AT ct_overwrite ASSIGNING <ls_overwrite>.
READ TABLE lt_selected WITH KEY
obj_type = <ls_overwrite>-obj_type
obj_name = <ls_overwrite>-obj_name
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
<ls_overwrite>-decision = 'Y'.
ELSE.
<ls_overwrite>-decision = 'N'.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD popup_package_overwrite.
DATA: lv_question TYPE c LENGTH 200,
lv_answer TYPE c.
FIELD-SYMBOLS: <ls_overwrite> LIKE LINE OF ct_overwrite.
IF lines( ct_overwrite ) = 0.
RETURN.
ENDIF.
LOOP AT ct_overwrite ASSIGNING <ls_overwrite>.
CONCATENATE 'Overwrite object' <ls_overwrite>-obj_type <ls_overwrite>-obj_name
'from package' <ls_overwrite>-devclass
INTO lv_question SEPARATED BY space. "#EC NOTEXT
lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm(
iv_titlebar = 'Warning'
iv_text_question = lv_question
iv_text_button_1 = 'Ok'
iv_icon_button_1 = 'ICON_DELETE'
iv_text_button_2 = 'Cancel'
iv_icon_button_2 = 'ICON_CANCEL'
iv_default_button = '2'
iv_display_cancel_button = abap_false ). "#EC NOTEXT
IF lv_answer = '2'.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
<ls_overwrite>-decision = 'Y'.
ENDLOOP.
ENDMETHOD.
METHOD purge.
DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt,
lv_answer TYPE c LENGTH 1,
lo_repo TYPE REF TO zcl_abapgit_repo,
lv_package TYPE devclass,
lv_question TYPE c LENGTH 100,
ls_checks TYPE zif_abapgit_definitions=>ty_delete_checks.
lo_repo = zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
lv_package = lo_repo->get_package( ).
lt_tadir = zcl_abapgit_factory=>get_tadir( )->read( lv_package ).
IF lines( lt_tadir ) > 0.
lv_question = |This will DELETE all objects in package { lv_package
} ({ lines( lt_tadir ) } objects) from the system|. "#EC NOTEXT
lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm(
iv_titlebar = 'Uninstall'
iv_text_question = lv_question
iv_text_button_1 = 'Delete'
iv_icon_button_1 = 'ICON_DELETE'
iv_text_button_2 = 'Cancel'
iv_icon_button_2 = 'ICON_CANCEL'
iv_default_button = '2'
iv_display_cancel_button = abap_false ). "#EC NOTEXT
IF lv_answer = '2'.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
ENDIF.
ls_checks = lo_repo->delete_checks( ).
IF ls_checks-transport-required = abap_true.
ls_checks-transport-transport = zcl_abapgit_ui_factory=>get_popups(
)->popup_transport_request( ls_checks-transport-type ).
ENDIF.
zcl_abapgit_repo_srv=>get_instance( )->purge( io_repo = lo_repo
is_checks = ls_checks ).
COMMIT WORK.
ENDMETHOD.
METHOD refresh.
zcl_abapgit_repo_srv=>get_instance( )->get( iv_key )->refresh( ).
ENDMETHOD. "refresh
METHOD refresh_local_checksums.
DATA: lv_answer TYPE c,
lv_question TYPE string,
lo_repo TYPE REF TO zcl_abapgit_repo.
IF zcl_abapgit_auth=>is_allowed( zif_abapgit_auth=>gc_authorization-update_local_checksum ) = abap_false.
zcx_abapgit_exception=>raise( 'Not authorized' ).
ENDIF.
lo_repo = zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
lv_question = 'This will rebuild and overwrite local repo checksums.'.
IF lo_repo->is_offline( ) = abap_false.
lv_question = lv_question
&& ' The logic: if local and remote file differs then:'
&& ' if remote branch is ahead then assume changes are remote,'
&& ' else (branches are equal) assume changes are local.'
&& ' This will lead to incorrect state for files changed on both sides.'
&& ' Please make sure you don''t have ones like that.'.
ENDIF.
lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm(
iv_titlebar = 'Warning'
iv_text_question = lv_question
iv_text_button_1 = 'OK'
iv_icon_button_1 = 'ICON_DELETE'
iv_text_button_2 = 'Cancel'
iv_icon_button_2 = 'ICON_CANCEL'
iv_default_button = '2'
iv_display_cancel_button = abap_false ). "#EC NOTEXT
IF lv_answer = '2'.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
lo_repo->rebuild_local_checksums( ).
COMMIT WORK AND WAIT.
ENDMETHOD.
METHOD remote_attach.
DATA: ls_popup TYPE zif_abapgit_popups=>ty_popup,
lo_repo TYPE REF TO zcl_abapgit_repo_online.
ls_popup = zcl_abapgit_ui_factory=>get_popups( )->repo_popup(
iv_title = 'Attach repo to remote ...'
iv_url = ''
iv_package = zcl_abapgit_repo_srv=>get_instance( )->get( iv_key )->get_package( )
iv_freeze_package = abap_true ).
IF ls_popup-cancel = abap_true.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
zcl_abapgit_repo_srv=>get_instance( )->switch_repo_type(
iv_key = iv_key
iv_offline = abap_false ).
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
lo_repo->set_url( ls_popup-url ).
lo_repo->set_branch_name( ls_popup-branch_name ).
COMMIT WORK.
ENDMETHOD.
METHOD remote_change.
DATA: ls_popup TYPE zif_abapgit_popups=>ty_popup,
lo_repo TYPE REF TO zcl_abapgit_repo_online.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
ls_popup = zcl_abapgit_ui_factory=>get_popups( )->repo_popup(
iv_title = 'Change repo remote ...'
iv_url = lo_repo->get_url( )
iv_package = lo_repo->get_package( )
iv_freeze_package = abap_true ).
IF ls_popup-cancel = abap_true.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
lo_repo->set_url( ls_popup-url ).
lo_repo->set_branch_name( ls_popup-branch_name ).
COMMIT WORK.
ENDMETHOD.
METHOD remote_detach.
DATA: lv_answer TYPE c LENGTH 1.
lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm(
iv_titlebar = 'Make repository OFF-line'
iv_text_question = 'This will detach the repo from remote and make it OFF-line'
iv_text_button_1 = 'Make OFF-line'
iv_icon_button_1 = 'ICON_WF_UNLINK'
iv_text_button_2 = 'Cancel'
iv_icon_button_2 = 'ICON_CANCEL'
iv_default_button = '2'
iv_display_cancel_button = abap_false ). "#EC NOTEXT
IF lv_answer = '2'.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
zcl_abapgit_repo_srv=>get_instance( )->switch_repo_type( iv_key = iv_key iv_offline = abap_true ).
COMMIT WORK.
ENDMETHOD.
METHOD remove.
DATA: lv_answer TYPE c LENGTH 1,
lo_repo TYPE REF TO zcl_abapgit_repo,
lv_package TYPE devclass,
lv_question TYPE c LENGTH 200.
lo_repo = zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
lv_package = lo_repo->get_package( ).
lv_question = |This will remove the repository reference to the package { lv_package
}. All objects will safely remain in the system.|.
lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm(
iv_titlebar = 'Remove'
iv_text_question = lv_question
iv_text_button_1 = 'Remove'
iv_icon_button_1 = 'ICON_WF_UNLINK'
iv_text_button_2 = 'Cancel'
iv_icon_button_2 = 'ICON_CANCEL'
iv_default_button = '2'
iv_display_cancel_button = abap_false ). "#EC NOTEXT
IF lv_answer = '2'.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
zcl_abapgit_repo_srv=>get_instance( )->delete( lo_repo ).
COMMIT WORK.
ENDMETHOD.
METHOD toggle_favorite.
zcl_abapgit_persistence_user=>get_instance( )->toggle_favorite( iv_key ).
ENDMETHOD.
METHOD transport_to_branch.
DATA:
lo_repository TYPE REF TO zcl_abapgit_repo_online,
lo_transport_to_branch TYPE REF TO zcl_abapgit_transport_2_branch,
lt_transport_headers TYPE trwbo_request_headers,
lt_transport_objects TYPE zif_abapgit_definitions=>ty_tadir_tt,
ls_transport_to_branch TYPE zif_abapgit_definitions=>ty_transport_to_branch.
IF zcl_abapgit_auth=>is_allowed( zif_abapgit_auth=>gc_authorization-transport_to_branch ) = abap_false.
zcx_abapgit_exception=>raise( 'Not authorized' ).
ENDIF.
lo_repository ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_repository_key ).
lt_transport_headers = zcl_abapgit_ui_factory=>get_popups( )->popup_to_select_transports( ).
lt_transport_objects = zcl_abapgit_transport=>to_tadir( lt_transport_headers ).
IF lt_transport_objects IS INITIAL.
zcx_abapgit_exception=>raise( 'Canceled or List of objects is empty ' ).
ENDIF.
ls_transport_to_branch = zcl_abapgit_ui_factory=>get_popups( )->popup_to_create_transp_branch(
lt_transport_headers ).
CREATE OBJECT lo_transport_to_branch.
lo_transport_to_branch->create(
io_repository = lo_repository
is_transport_to_branch = ls_transport_to_branch
it_transport_objects = lt_transport_objects ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_SERVICES_GIT IMPLEMENTATION.
METHOD commit.
DATA: ls_comment TYPE zif_abapgit_definitions=>ty_comment,
li_user TYPE REF TO zif_abapgit_persist_user.
li_user = zcl_abapgit_persistence_user=>get_instance( ).
li_user->set_repo_git_user_name( iv_url = io_repo->get_url( )
iv_username = is_commit-committer_name ).
li_user->set_repo_git_user_email( iv_url = io_repo->get_url( )
iv_email = is_commit-committer_email ).
IF is_commit-committer_name IS INITIAL.
zcx_abapgit_exception=>raise( 'Commit: Committer name empty' ).
ELSEIF is_commit-committer_email IS INITIAL.
zcx_abapgit_exception=>raise( 'Commit: Committer email empty' ).
ELSEIF is_commit-author_email IS NOT INITIAL AND is_commit-author_name IS INITIAL.
zcx_abapgit_exception=>raise( 'Commit: Author name empty' ). " Opposite should be OK ?
ELSEIF is_commit-comment IS INITIAL.
zcx_abapgit_exception=>raise( 'Commit: empty comment' ).
ENDIF.
ls_comment-committer-name = is_commit-committer_name.
ls_comment-committer-email = is_commit-committer_email.
ls_comment-author-name = is_commit-author_name.
ls_comment-author-email = is_commit-author_email.
ls_comment-comment = is_commit-comment.
IF NOT is_commit-body IS INITIAL.
CONCATENATE ls_comment-comment '' is_commit-body
INTO ls_comment-comment SEPARATED BY zif_abapgit_definitions=>c_newline.
ENDIF.
io_repo->push( is_comment = ls_comment
io_stage = io_stage ).
COMMIT WORK.
ENDMETHOD.
METHOD create_branch.
DATA: lv_name TYPE string,
lv_cancel TYPE abap_bool,
lo_repo TYPE REF TO zcl_abapgit_repo_online,
li_popups TYPE REF TO zif_abapgit_popups.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
li_popups = zcl_abapgit_ui_factory=>get_popups( ).
li_popups->create_branch_popup(
IMPORTING
ev_name = lv_name
ev_cancel = lv_cancel ).
IF lv_cancel = abap_true.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
lo_repo->create_branch( lv_name ).
MESSAGE 'Switched to new branch' TYPE 'S' ##NO_TEXT.
ENDMETHOD.
METHOD delete_branch.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
ls_branch TYPE zif_abapgit_definitions=>ty_git_branch.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
ls_branch = zcl_abapgit_ui_factory=>get_popups( )->branch_list_popup( lo_repo->get_url( ) ).
IF ls_branch IS INITIAL.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
IF ls_branch-name = 'HEAD'.
zcx_abapgit_exception=>raise( 'Cannot delete HEAD' ).
ELSEIF ls_branch-name = lo_repo->get_branch_name( ).
zcx_abapgit_exception=>raise( 'Switch branch before deleting current' ).
ENDIF.
zcl_abapgit_git_porcelain=>delete_branch(
iv_url = lo_repo->get_url( )
is_branch = ls_branch ).
MESSAGE 'Branch deleted' TYPE 'S'.
ENDMETHOD.
METHOD delete_tag.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
ls_tag TYPE zif_abapgit_definitions=>ty_git_tag,
lv_text TYPE string.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
ls_tag = zcl_abapgit_ui_factory=>get_tag_popups( )->tag_select_popup( lo_repo ).
IF ls_tag IS INITIAL.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
zcl_abapgit_git_porcelain=>delete_tag(
iv_url = lo_repo->get_url( )
is_tag = ls_tag ).
lv_text = |Tag { zcl_abapgit_tag=>remove_tag_prefix( ls_tag-name ) } deleted| ##NO_TEXT.
MESSAGE lv_text TYPE 'S'.
ENDMETHOD.
METHOD pull.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
lo_repo->refresh( ).
zcl_abapgit_services_repo=>gui_deserialize( lo_repo ).
COMMIT WORK.
ENDMETHOD. "pull
METHOD reset.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
lv_answer TYPE c LENGTH 1,
lt_unnecessary_local_objs TYPE zif_abapgit_definitions=>ty_tadir_tt,
lt_selected LIKE lt_unnecessary_local_objs,
lt_columns TYPE stringtab,
ls_checks TYPE zif_abapgit_definitions=>ty_delete_checks,
li_popups TYPE REF TO zif_abapgit_popups.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
IF lo_repo->get_local_settings( )-write_protected = abap_true.
zcx_abapgit_exception=>raise( 'Cannot reset. Local code is write-protected by repo config' ).
ENDIF.
lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm(
iv_titlebar = 'Warning'
iv_text_question = 'Reset local objects?'
iv_text_button_1 = 'Ok'
iv_icon_button_1 = 'ICON_OKAY'
iv_text_button_2 = 'Cancel'
iv_icon_button_2 = 'ICON_CANCEL'
iv_default_button = '2'
iv_display_cancel_button = abap_false ). "#EC NOTEXT
IF lv_answer = '2'.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
lt_unnecessary_local_objs = lo_repo->get_unnecessary_local_objs( ).
IF lines( lt_unnecessary_local_objs ) > 0.
INSERT `OBJECT` INTO TABLE lt_columns.
INSERT `OBJ_NAME` INTO TABLE lt_columns.
li_popups = zcl_abapgit_ui_factory=>get_popups( ).
li_popups->popup_to_select_from_list(
EXPORTING
it_list = lt_unnecessary_local_objs
iv_header_text = |Which unnecessary objects should be deleted?|
iv_select_column_text = 'Delete?'
it_columns_to_display = lt_columns
IMPORTING
et_list = lt_selected ).
IF lines( lt_selected ) > 0.
ls_checks = lo_repo->delete_checks( ).
IF ls_checks-transport-required = abap_true.
ls_checks-transport-transport = zcl_abapgit_ui_factory=>get_popups(
)->popup_transport_request( ls_checks-transport-type ).
ENDIF.
zcl_abapgit_objects=>delete( it_tadir = lt_selected
is_checks = ls_checks ).
lo_repo->refresh( ).
ENDIF.
ENDIF.
zcl_abapgit_services_repo=>gui_deserialize( lo_repo ).
ENDMETHOD.
METHOD switch_branch.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
ls_branch TYPE zif_abapgit_definitions=>ty_git_branch.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
ls_branch = zcl_abapgit_ui_factory=>get_popups( )->branch_list_popup(
iv_url = lo_repo->get_url( )
iv_default_branch = lo_repo->get_branch_name( )
iv_show_new_option = abap_true ).
IF ls_branch IS INITIAL.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
IF ls_branch-name = zcl_abapgit_ui_factory=>get_popups( )->c_new_branch_label.
create_branch( iv_key ).
RETURN.
ENDIF.
lo_repo->set_branch_name( ls_branch-name ).
COMMIT WORK AND WAIT.
ENDMETHOD.
METHOD switch_tag.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
ls_tag TYPE zif_abapgit_definitions=>ty_git_tag.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
ls_tag = zcl_abapgit_ui_factory=>get_tag_popups( )->tag_select_popup( lo_repo ).
IF ls_tag IS INITIAL.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
lo_repo->set_branch_name( ls_tag-name ).
COMMIT WORK AND WAIT.
ENDMETHOD.
METHOD tag_overview.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
zcl_abapgit_ui_factory=>get_tag_popups( )->tag_list_popup( lo_repo ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_services_abapgit IMPLEMENTATION.
METHOD do_install.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
lv_answer TYPE c LENGTH 1.
lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm(
iv_titlebar = iv_title
iv_text_question = iv_text
iv_text_button_1 = 'Continue'
iv_text_button_2 = 'Cancel'
iv_default_button = '2'
iv_display_cancel_button = abap_false ). "#EC NOTEXT
IF lv_answer <> '1'.
RETURN.
ENDIF.
IF abap_false = zcl_abapgit_repo_srv=>get_instance( )->is_repo_installed(
iv_url = iv_url
iv_target_package = iv_package ).
zcl_abapgit_factory=>get_sap_package( iv_package )->create_local( ).
lo_repo = zcl_abapgit_repo_srv=>get_instance( )->new_online(
iv_url = iv_url
iv_branch_name = 'refs/heads/master'
iv_package = iv_package ) ##NO_TEXT.
zcl_abapgit_services_repo=>gui_deserialize( lo_repo ).
zcl_abapgit_services_repo=>toggle_favorite( lo_repo->get_key( ) ).
ENDIF.
COMMIT WORK.
ENDMETHOD.
METHOD install_abapgit.
CONSTANTS lc_title TYPE c LENGTH 40 VALUE 'Install abapGit'.
DATA lv_text TYPE c LENGTH 100.
IF is_installed( ) = abap_true.
lv_text = 'Seems like abapGit package is already installed. No changes to be done'.
zcl_abapgit_ui_factory=>get_popups( )->popup_to_inform(
iv_titlebar = lc_title
iv_text_message = lv_text ).
RETURN.
ENDIF.
lv_text = |Confirm to install current version of abapGit to package { c_package_abapgit }|.
do_install( iv_title = lc_title
iv_text = lv_text
iv_url = c_abapgit_url
iv_package = c_package_abapgit ).
ENDMETHOD.
METHOD is_installed.
TRY.
rv_installed = zcl_abapgit_repo_srv=>get_instance( )->is_repo_installed( c_abapgit_url ).
" TODO, alternative checks for presence in the system
CATCH zcx_abapgit_exception.
" cannot be installed anyway in this case, e.g. no connection
rv_installed = abap_false.
ENDTRY.
ENDMETHOD.
METHOD open_abapgit_homepage.
cl_gui_frontend_services=>execute(
EXPORTING document = c_abapgit_homepage
EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Opening page in external browser failed.' ).
ENDIF.
ENDMETHOD.
METHOD open_abapgit_wikipage.
cl_gui_frontend_services=>execute(
EXPORTING document = c_abapgit_wikipage
EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Opening page in external browser failed.' ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_popups IMPLEMENTATION.
METHOD add_field.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF ct_fields.
APPEND INITIAL LINE TO ct_fields ASSIGNING <ls_field>.
<ls_field>-tabname = iv_tabname.
<ls_field>-fieldname = iv_fieldname.
<ls_field>-fieldtext = iv_fieldtext.
<ls_field>-value = iv_value.
<ls_field>-field_attr = iv_field_attr.
<ls_field>-field_obl = iv_obligatory.
ENDMETHOD.
METHOD zif_abapgit_popups~branch_list_popup.
DATA: lo_branches TYPE REF TO zcl_abapgit_git_branch_list,
lt_branches TYPE zif_abapgit_definitions=>ty_git_branch_list_tt,
lv_answer TYPE c LENGTH 1,
lv_default TYPE i,
lv_head_suffix TYPE string,
lv_head_symref TYPE string,
lt_selection TYPE TABLE OF spopli.
FIELD-SYMBOLS: <ls_sel> LIKE LINE OF lt_selection,
<ls_branch> LIKE LINE OF lt_branches.
lo_branches = zcl_abapgit_git_transport=>branches( iv_url ).
lt_branches = lo_branches->get_branches_only( ).
lv_head_suffix = | ({ zif_abapgit_definitions=>c_head_name })|.
lv_head_symref = lo_branches->get_head_symref( ).
LOOP AT lt_branches ASSIGNING <ls_branch>.
CHECK <ls_branch>-name IS NOT INITIAL. " To ensure some below ifs
IF <ls_branch>-is_head = abap_true.
IF <ls_branch>-name = zif_abapgit_definitions=>c_head_name. " HEAD
IF <ls_branch>-name <> lv_head_symref AND lv_head_symref IS NOT INITIAL.
" HEAD but other HEAD symref exists - ignore
CONTINUE.
ELSE.
INSERT INITIAL LINE INTO lt_selection INDEX 1 ASSIGNING <ls_sel>.
<ls_sel>-varoption = <ls_branch>-name.
ENDIF.
ELSE.
INSERT INITIAL LINE INTO lt_selection INDEX 1 ASSIGNING <ls_sel>.
<ls_sel>-varoption = <ls_branch>-display_name && lv_head_suffix.
ENDIF.
IF lv_default > 0. " Shift down default if set
lv_default = lv_default + 1.
ENDIF.
ELSE.
APPEND INITIAL LINE TO lt_selection ASSIGNING <ls_sel>.
<ls_sel>-varoption = <ls_branch>-display_name.
ENDIF.
IF <ls_branch>-name = iv_default_branch.
IF <ls_branch>-is_head = abap_true.
lv_default = 1.
ELSE.
lv_default = sy-tabix.
ENDIF.
ENDIF.
ENDLOOP.
IF iv_show_new_option = abap_true.
APPEND INITIAL LINE TO lt_selection ASSIGNING <ls_sel>.
<ls_sel>-varoption = zif_abapgit_popups=>c_new_branch_label.
ENDIF.
CALL FUNCTION 'POPUP_TO_DECIDE_LIST'
EXPORTING
textline1 = 'Select branch'
titel = 'Select branch'
start_col = 30
start_row = 5
cursorline = lv_default
IMPORTING
answer = lv_answer
TABLES
t_spopli = lt_selection
EXCEPTIONS
not_enough_answers = 1
too_much_answers = 2
too_much_marks = 3
OTHERS = 4. "#EC NOTEXT
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_TO_DECIDE_LIST' ).
ENDIF.
IF lv_answer = 'A'. " cancel
RETURN.
ENDIF.
READ TABLE lt_selection ASSIGNING <ls_sel> WITH KEY selflag = abap_true.
ASSERT sy-subrc = 0.
IF iv_show_new_option = abap_true AND <ls_sel>-varoption = zif_abapgit_popups=>c_new_branch_label.
rs_branch-name = zif_abapgit_popups=>c_new_branch_label.
ELSE.
REPLACE FIRST OCCURRENCE OF lv_head_suffix IN <ls_sel>-varoption WITH ''.
READ TABLE lt_branches WITH KEY display_name = <ls_sel>-varoption ASSIGNING <ls_branch>.
IF sy-subrc <> 0.
LOOP AT lt_branches ASSIGNING <ls_branch> WHERE display_name CS <ls_sel>-varoption.
EXIT. " current loop
ENDLOOP.
ENDIF.
ASSERT <ls_branch> IS ASSIGNED.
rs_branch = lo_branches->find_by_name( <ls_branch>-name ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_popups~branch_popup_callback.
DATA: lv_url TYPE string,
ls_package_data TYPE scompkdtln,
ls_branch TYPE zif_abapgit_definitions=>ty_git_branch,
lv_create TYPE boolean.
FIELD-SYMBOLS: <ls_furl> LIKE LINE OF ct_fields,
<ls_fbranch> LIKE LINE OF ct_fields,
<ls_fpackage> LIKE LINE OF ct_fields.
CLEAR cs_error.
IF iv_code = 'COD1'.
cv_show_popup = abap_true.
READ TABLE ct_fields ASSIGNING <ls_furl> WITH KEY tabname = 'ABAPTXT255'.
IF sy-subrc <> 0 OR <ls_furl>-value IS INITIAL.
MESSAGE 'Fill URL' TYPE 'S' DISPLAY LIKE 'E'. "#EC NOTEXT
RETURN.
ENDIF.
lv_url = <ls_furl>-value.
ls_branch = branch_list_popup( lv_url ).
IF ls_branch IS INITIAL.
RETURN.
ENDIF.
READ TABLE ct_fields ASSIGNING <ls_fbranch> WITH KEY tabname = 'TEXTL'.
ASSERT sy-subrc = 0.
<ls_fbranch>-value = ls_branch-name.
ELSEIF iv_code = 'COD2'.
cv_show_popup = abap_true.
READ TABLE ct_fields ASSIGNING <ls_fpackage> WITH KEY fieldname = 'DEVCLASS'.
ASSERT sy-subrc = 0.
ls_package_data-devclass = <ls_fpackage>-value.
popup_to_create_package(
IMPORTING
es_package_data = ls_package_data
ev_create = lv_create ).
IF lv_create = abap_false.
RETURN.
ENDIF.
zcl_abapgit_factory=>get_sap_package( ls_package_data-devclass )->create( ls_package_data ).
COMMIT WORK.
<ls_fpackage>-value = ls_package_data-devclass.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_popups~create_branch_popup.
DATA: lv_answer TYPE c LENGTH 1,
lt_fields TYPE TABLE OF sval.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
CLEAR: ev_name, ev_cancel.
add_field( EXPORTING iv_tabname = 'TEXTL'
iv_fieldname = 'LINE'
iv_fieldtext = 'Name'
iv_value = 'new-branch-name'
CHANGING ct_fields = lt_fields ).
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
popup_title = 'Create branch'
IMPORTING
returncode = lv_answer
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2 ##NO_TEXT.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_answer = 'A'.
ev_cancel = abap_true.
ELSE.
READ TABLE lt_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
ev_name = zcl_abapgit_git_branch_list=>complete_heads_branch_name(
zcl_abapgit_git_branch_list=>normalize_branch_name( <ls_field>-value ) ).
ENDIF.
ENDMETHOD.
METHOD create_new_table.
" create and populate a table on the fly derived from
" it_data with a select column
DATA: lr_struct TYPE REF TO data,
lt_components TYPE cl_abap_structdescr=>component_table,
lo_struct_descr TYPE REF TO cl_abap_structdescr,
struct_descr TYPE REF TO cl_abap_structdescr.
FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE,
<ls_component> TYPE abap_componentdescr,
<lg_line> TYPE data,
<lg_data> TYPE any.
go_table_descr ?= cl_abap_tabledescr=>describe_by_data( it_list ).
lo_struct_descr ?= go_table_descr->get_table_line_type( ).
lt_components = lo_struct_descr->get_components( ).
INSERT INITIAL LINE INTO lt_components ASSIGNING <ls_component> INDEX 1.
ASSERT sy-subrc = 0.
<ls_component>-name = c_fieldname_selected.
<ls_component>-type ?= cl_abap_datadescr=>describe_by_name( 'FLAG' ).
struct_descr = cl_abap_structdescr=>create( lt_components ).
go_table_descr = cl_abap_tabledescr=>create( struct_descr ).
CREATE DATA gr_table TYPE HANDLE go_table_descr.
ASSIGN gr_table->* TO <lt_table>.
ASSERT sy-subrc = 0.
CREATE DATA lr_struct TYPE HANDLE struct_descr.
ASSIGN lr_struct->* TO <lg_line>.
ASSERT sy-subrc = 0.
LOOP AT it_list ASSIGNING <lg_data>.
CLEAR <lg_line>.
MOVE-CORRESPONDING <lg_data> TO <lg_line>.
INSERT <lg_line> INTO TABLE <lt_table>.
ENDLOOP.
ENDMETHOD.
METHOD extract_field_values.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF it_fields.
CLEAR: ev_url,
ev_package,
ev_branch.
READ TABLE it_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
ev_url = <ls_field>-value.
READ TABLE it_fields INDEX 2 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
ev_package = <ls_field>-value.
TRANSLATE ev_package TO UPPER CASE.
READ TABLE it_fields INDEX 3 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
ev_branch = <ls_field>-value.
ENDMETHOD.
METHOD get_selected_rows.
DATA: lv_condition TYPE string,
lr_exporting TYPE REF TO data.
FIELD-SYMBOLS: <lg_exporting> TYPE any,
<lt_table> TYPE STANDARD TABLE,
<lg_line> TYPE any.
lv_condition = |{ c_fieldname_selected } = ABAP_TRUE|.
ASSIGN gr_table->* TO <lt_table>.
ASSERT sy-subrc = 0.
CREATE DATA lr_exporting LIKE LINE OF et_list.
ASSIGN lr_exporting->* TO <lg_exporting>.
LOOP AT <lt_table> ASSIGNING <lg_line> WHERE (lv_condition).
CLEAR <lg_exporting>.
MOVE-CORRESPONDING <lg_line> TO <lg_exporting>.
APPEND <lg_exporting> TO et_list.
ENDLOOP.
ENDMETHOD.
METHOD on_select_list_function_click.
FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE,
<lg_line> TYPE any,
<lv_selected> TYPE flag.
ASSIGN gr_table->* TO <lt_table>.
ASSERT sy-subrc = 0.
CASE e_salv_function.
WHEN 'O.K.'.
gv_cancel = abap_false.
go_select_list_popup->close_screen( ).
WHEN 'ABR'.
"Canceled: clear list to overwrite nothing
CLEAR <lt_table>.
gv_cancel = abap_true.
go_select_list_popup->close_screen( ).
WHEN 'SALL'.
LOOP AT <lt_table> ASSIGNING <lg_line>.
ASSIGN COMPONENT c_fieldname_selected
OF STRUCTURE <lg_line>
TO <lv_selected>.
ASSERT sy-subrc = 0.
<lv_selected> = abap_true.
ENDLOOP.
go_select_list_popup->refresh( ).
WHEN 'DSEL'.
LOOP AT <lt_table> ASSIGNING <lg_line>.
ASSIGN COMPONENT c_fieldname_selected
OF STRUCTURE <lg_line>
TO <lv_selected>.
ASSERT sy-subrc = 0.
<lv_selected> = abap_false.
ENDLOOP.
go_select_list_popup->refresh( ).
WHEN OTHERS.
CLEAR <lt_table>.
go_select_list_popup->close_screen( ).
ENDCASE.
ENDMETHOD.
METHOD on_select_list_link_click.
DATA: lv_line TYPE sytabix.
FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE,
<lg_line> TYPE any,
<lv_selected> TYPE flag.
ASSIGN gr_table->* TO <lt_table>.
ASSERT sy-subrc = 0.
lv_line = row.
READ TABLE <lt_table> ASSIGNING <lg_line>
INDEX lv_line.
IF sy-subrc = 0.
ASSIGN COMPONENT c_fieldname_selected
OF STRUCTURE <lg_line>
TO <lv_selected>.
ASSERT sy-subrc = 0.
IF <lv_selected> = abap_true.
<lv_selected> = abap_false.
ELSE.
<lv_selected> = abap_true.
ENDIF.
ENDIF.
go_select_list_popup->refresh( ).
ENDMETHOD.
METHOD zif_abapgit_popups~package_popup_callback.
DATA: ls_package_data TYPE scompkdtln,
lv_create TYPE boolean.
FIELD-SYMBOLS: <ls_fpackage> LIKE LINE OF ct_fields.
CLEAR cs_error.
IF iv_code = 'COD1'.
cv_show_popup = abap_true.
READ TABLE ct_fields ASSIGNING <ls_fpackage> WITH KEY fieldname = 'DEVCLASS'.
ASSERT sy-subrc = 0.
ls_package_data-devclass = <ls_fpackage>-value.
popup_to_create_package( IMPORTING es_package_data = ls_package_data
ev_create = lv_create ).
IF lv_create = abap_false.
RETURN.
ENDIF.
zcl_abapgit_factory=>get_sap_package( ls_package_data-devclass )->create( ls_package_data ).
COMMIT WORK.
<ls_fpackage>-value = ls_package_data-devclass.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_popups~popup_folder_logic.
DATA: lv_returncode TYPE c,
lt_fields TYPE TABLE OF sval.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
add_field( EXPORTING iv_tabname = 'TDEVC'
iv_fieldname = 'INTSYS'
iv_fieldtext = 'Folder logic'
iv_value = 'PREFIX'
CHANGING ct_fields = lt_fields ).
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
no_value_check = abap_true
popup_title = 'Export package' "#EC NOTEXT
IMPORTING
returncode = lv_returncode
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_returncode = 'A'.
RETURN.
ENDIF.
READ TABLE lt_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
TRANSLATE <ls_field>-value TO UPPER CASE.
rv_folder_logic = <ls_field>-value.
ENDMETHOD. "popup_package_export
METHOD zif_abapgit_popups~popup_object.
DATA: lv_returncode TYPE c,
lt_fields TYPE TABLE OF sval.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
add_field( EXPORTING iv_tabname = 'TADIR'
iv_fieldname = 'OBJECT'
iv_fieldtext = 'Type'
CHANGING ct_fields = lt_fields ).
add_field( EXPORTING iv_tabname = 'TADIR'
iv_fieldname = 'OBJ_NAME'
iv_fieldtext = 'Name'
CHANGING ct_fields = lt_fields ).
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
no_value_check = abap_true
popup_title = 'Object' "#EC NOTEXT
IMPORTING
returncode = lv_returncode
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_returncode = 'A'.
RETURN.
ENDIF.
READ TABLE lt_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
TRANSLATE <ls_field>-value TO UPPER CASE.
rs_tadir-object = <ls_field>-value.
READ TABLE lt_fields INDEX 2 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
TRANSLATE <ls_field>-value TO UPPER CASE.
rs_tadir-obj_name = <ls_field>-value.
rs_tadir = zcl_abapgit_factory=>get_tadir( )->read_single(
iv_object = rs_tadir-object
iv_obj_name = rs_tadir-obj_name ).
ENDMETHOD.
METHOD zif_abapgit_popups~popup_package_export.
DATA: lv_returncode TYPE c,
lt_fields TYPE TABLE OF sval.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
add_field( EXPORTING iv_tabname = 'TDEVC'
iv_fieldname = 'DEVCLASS'
iv_fieldtext = 'Package'
CHANGING ct_fields = lt_fields ).
add_field( EXPORTING iv_tabname = 'TDEVC'
iv_fieldname = 'INTSYS'
iv_fieldtext = 'Folder logic'
iv_value = 'PREFIX'
CHANGING ct_fields = lt_fields ).
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
no_value_check = abap_true
popup_title = 'Export package' "#EC NOTEXT
IMPORTING
returncode = lv_returncode
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_returncode = 'A'.
RETURN.
ENDIF.
READ TABLE lt_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
TRANSLATE <ls_field>-value TO UPPER CASE.
ev_package = <ls_field>-value.
READ TABLE lt_fields INDEX 2 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
TRANSLATE <ls_field>-value TO UPPER CASE.
ev_folder_logic = <ls_field>-value.
ENDMETHOD. "popup_package_export
METHOD zif_abapgit_popups~popup_to_confirm.
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
titlebar = iv_titlebar
text_question = iv_text_question
text_button_1 = iv_text_button_1
icon_button_1 = iv_icon_button_1
text_button_2 = iv_text_button_2
icon_button_2 = iv_icon_button_2
default_button = iv_default_button
display_cancel_button = iv_display_cancel_button
IMPORTING
answer = rv_answer
EXCEPTIONS
text_not_found = 1
OTHERS = 2. "#EC NOTEXT
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from POPUP_TO_CONFIRM' ).
ENDIF.
ENDMETHOD. "popup_to_confirm
METHOD zif_abapgit_popups~popup_to_create_package.
CALL FUNCTION 'FUNCTION_EXISTS'
EXPORTING
funcname = 'PB_POPUP_PACKAGE_CREATE'
EXCEPTIONS
function_not_exist = 1
OTHERS = 2.
IF sy-subrc = 1.
zcx_abapgit_exception=>raise( 'Your system does not support automatic creation of packages.' &&
'Please, create the package manually.' ).
ENDIF.
CALL FUNCTION 'PB_POPUP_PACKAGE_CREATE'
CHANGING
p_object_data = es_package_data
EXCEPTIONS
action_cancelled = 1.
IF sy-subrc = 0.
ev_create = abap_true.
ELSE.
ev_create = abap_false.
ENDIF.
ENDMETHOD. " popup_to_create_package
METHOD zif_abapgit_popups~popup_to_create_transp_branch.
DATA: lv_returncode TYPE c,
lt_fields TYPE TABLE OF sval,
lv_transports_as_text TYPE string,
ls_transport_header LIKE LINE OF it_transport_headers.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
lv_transports_as_text = 'Transport(s)'.
LOOP AT it_transport_headers INTO ls_transport_header.
CONCATENATE lv_transports_as_text '_' ls_transport_header-trkorr INTO lv_transports_as_text.
ENDLOOP.
add_field( EXPORTING iv_tabname = 'TEXTL'
iv_fieldname = 'LINE'
iv_fieldtext = 'Branch name'
iv_value = lv_transports_as_text
CHANGING ct_fields = lt_fields ).
add_field( EXPORTING iv_tabname = 'ABAPTXT255'
iv_fieldname = 'LINE'
iv_fieldtext = 'Commit text'
iv_value = lv_transports_as_text
CHANGING ct_fields = lt_fields ).
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
popup_title = 'Transport to new Branch'
IMPORTING
returncode = lv_returncode
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_returncode = 'A'.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
READ TABLE lt_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
rs_transport_branch-branch_name = <ls_field>-value.
READ TABLE lt_fields INDEX 2 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
rs_transport_branch-commit_text = <ls_field>-value.
ENDMETHOD.
METHOD zif_abapgit_popups~popup_to_inform.
DATA: lv_line1 TYPE char70,
lv_line2 TYPE char70.
lv_line1 = iv_text_message.
IF strlen( iv_text_message ) > 70.
lv_line2 = iv_text_message+70.
ENDIF.
CALL FUNCTION 'POPUP_TO_INFORM'
EXPORTING
titel = iv_titlebar
txt1 = lv_line1
txt2 = lv_line2.
ENDMETHOD. " popup_to_inform.
METHOD zif_abapgit_popups~popup_to_select_from_list.
DATA:
lo_events TYPE REF TO cl_salv_events_table,
lo_columns TYPE REF TO cl_salv_columns_table,
lt_columns TYPE salv_t_column_ref,
ls_column TYPE salv_s_column_ref,
lo_column TYPE REF TO cl_salv_column_list,
lo_table_header TYPE REF TO cl_salv_form_text.
FIELD-SYMBOLS: <lt_table> TYPE STANDARD TABLE.
CLEAR: et_list.
create_new_table( it_list ).
ASSIGN gr_table->* TO <lt_table>.
ASSERT sy-subrc = 0.
TRY.
cl_salv_table=>factory( IMPORTING r_salv_table = go_select_list_popup
CHANGING t_table = <lt_table> ).
go_select_list_popup->set_screen_status( pfstatus = '102'
report = 'SAPMSVIM' ).
go_select_list_popup->set_screen_popup( start_column = 1
end_column = 65
start_line = 1
end_line = 20 ).
lo_events = go_select_list_popup->get_event( ).
SET HANDLER on_select_list_link_click FOR lo_events.
SET HANDLER on_select_list_function_click FOR lo_events.
CREATE OBJECT lo_table_header
EXPORTING
text = iv_header_text.
go_select_list_popup->set_top_of_list( lo_table_header ).
lo_columns = go_select_list_popup->get_columns( ).
lo_columns->set_optimize( abap_true ).
lt_columns = lo_columns->get( ).
LOOP AT lt_columns INTO ls_column.
IF ls_column-columnname = c_fieldname_selected.
lo_column ?= ls_column-r_column.
lo_column->set_cell_type( if_salv_c_cell_type=>checkbox_hotspot ).
lo_column->set_output_length( 20 ).
lo_column->set_short_text( |{ iv_select_column_text }| ).
lo_column->set_medium_text( |{ iv_select_column_text }| ).
lo_column->set_long_text( |{ iv_select_column_text }| ).
CONTINUE.
ENDIF.
READ TABLE it_columns_to_display TRANSPORTING NO FIELDS
WITH KEY table_line = ls_column-columnname.
IF sy-subrc <> 0.
ls_column-r_column->set_technical( abap_true ).
ENDIF.
ENDLOOP.
go_select_list_popup->display( ).
CATCH cx_salv_msg.
zcx_abapgit_exception=>raise( 'Error from POPUP_TO_SELECT_FROM_LIST' ).
ENDTRY.
IF gv_cancel = abap_true.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
get_selected_rows(
IMPORTING
et_list = et_list ).
CLEAR: go_select_list_popup,
gr_table,
go_table_descr.
ENDMETHOD.
METHOD zif_abapgit_popups~popup_to_select_transports.
DATA: lv_trkorr TYPE e070-trkorr,
ls_trkorr LIKE LINE OF rt_trkorr.
CALL FUNCTION 'TR_F4_REQUESTS'
IMPORTING
ev_selected_request = lv_trkorr.
IF NOT lv_trkorr IS INITIAL.
ls_trkorr-trkorr = lv_trkorr.
APPEND ls_trkorr TO rt_trkorr.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_popups~popup_transport_request.
DATA: lt_e071 TYPE STANDARD TABLE OF e071,
lt_e071k TYPE STANDARD TABLE OF e071k.
CALL FUNCTION 'TRINT_ORDER_CHOICE'
EXPORTING
wi_order_type = is_transport_type-request
wi_task_type = is_transport_type-task
IMPORTING
we_order = rv_transport
TABLES
wt_e071 = lt_e071
wt_e071k = lt_e071k
EXCEPTIONS
no_correction_selected = 1
display_mode = 2
object_append_error = 3
recursive_call = 4
wrong_order_type = 5
OTHERS = 6.
IF sy-subrc = 1.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ELSEIF sy-subrc > 1.
zcx_abapgit_exception=>raise( |Error from TRINT_ORDER_CHOICE { sy-subrc }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_popups~repo_new_offline.
DATA: lv_returncode TYPE c,
lt_fields TYPE TABLE OF sval,
lv_icon_ok TYPE icon-name,
lv_button1 TYPE svalbutton-buttontext,
lv_icon1 TYPE icon-name,
lv_finished TYPE abap_bool,
lx_error TYPE REF TO zcx_abapgit_exception.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
add_field( EXPORTING iv_tabname = 'ABAPTXT255'
iv_fieldname = 'LINE'
iv_fieldtext = 'Name'
iv_obligatory = abap_true
CHANGING ct_fields = lt_fields ).
add_field( EXPORTING iv_tabname = 'TDEVC'
iv_fieldname = 'DEVCLASS'
iv_fieldtext = 'Package'
iv_obligatory = abap_true
CHANGING ct_fields = lt_fields ).
WHILE lv_finished = abap_false.
lv_icon_ok = icon_okay.
lv_button1 = 'Create package' ##NO_TEXT.
lv_icon1 = icon_folder.
CALL FUNCTION 'POPUP_GET_VALUES_USER_BUTTONS'
EXPORTING
popup_title = 'New Offline Project'
programname = sy-cprog
formname = 'PACKAGE_POPUP'
ok_pushbuttontext = ''
icon_ok_push = lv_icon_ok
first_pushbutton = lv_button1
icon_button_1 = lv_icon1
second_pushbutton = ''
icon_button_2 = ''
IMPORTING
returncode = lv_returncode
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_returncode = 'A'.
rs_popup-cancel = abap_true.
RETURN.
ENDIF.
READ TABLE lt_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
rs_popup-url = <ls_field>-value.
READ TABLE lt_fields INDEX 2 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
TRANSLATE <ls_field>-value TO UPPER CASE.
rs_popup-package = <ls_field>-value.
lv_finished = abap_true.
TRY.
zcl_abapgit_repo_srv=>get_instance( )->validate_package( rs_popup-package ).
CATCH zcx_abapgit_exception INTO lx_error.
" in case of validation errors we display the popup again
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
CLEAR lv_finished.
ENDTRY.
ENDWHILE.
ENDMETHOD. "repo_new_offline
METHOD zif_abapgit_popups~repo_popup.
DATA: lv_returncode TYPE c,
lv_icon_ok TYPE icon-name,
lv_icon_br TYPE icon-name,
lt_fields TYPE TABLE OF sval,
lv_uattr TYPE spo_fattr,
lv_pattr TYPE spo_fattr,
lv_button2 TYPE svalbutton-buttontext,
lv_icon2 TYPE icon-name,
lv_package TYPE tdevc-devclass,
lv_url TYPE abaptxt255-line,
lv_branch TYPE textl-line,
lv_finished TYPE abap_bool,
lx_error TYPE REF TO zcx_abapgit_exception.
IF iv_freeze_url = abap_true.
lv_uattr = '05'.
ENDIF.
IF iv_freeze_package = abap_true.
lv_pattr = '05'.
ENDIF.
IF iv_package IS INITIAL. " Empty package -> can be created
lv_button2 = 'Create package' ##NO_TEXT.
lv_icon2 = icon_folder.
ENDIF.
lv_package = iv_package.
lv_url = iv_url.
lv_branch = iv_branch.
WHILE lv_finished = abap_false.
CLEAR: lt_fields.
add_field( EXPORTING iv_tabname = 'ABAPTXT255'
iv_fieldname = 'LINE'
iv_fieldtext = 'Git clone URL'
iv_value = lv_url
iv_field_attr = lv_uattr
CHANGING ct_fields = lt_fields ).
add_field( EXPORTING iv_tabname = 'TDEVC'
iv_fieldname = 'DEVCLASS'
iv_fieldtext = 'Package'
iv_value = lv_package
iv_field_attr = lv_pattr
CHANGING ct_fields = lt_fields ).
add_field( EXPORTING iv_tabname = 'TEXTL'
iv_fieldname = 'LINE'
iv_fieldtext = 'Branch'
iv_value = lv_branch
iv_field_attr = '05'
CHANGING ct_fields = lt_fields ).
lv_icon_ok = icon_okay.
lv_icon_br = icon_workflow_fork.
CALL FUNCTION 'POPUP_GET_VALUES_USER_BUTTONS'
EXPORTING
popup_title = iv_title
programname = sy-cprog
formname = 'BRANCH_POPUP'
ok_pushbuttontext = 'OK'
icon_ok_push = lv_icon_ok
first_pushbutton = 'Select branch'
icon_button_1 = lv_icon_br
second_pushbutton = lv_button2
icon_button_2 = lv_icon2
IMPORTING
returncode = lv_returncode
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2. "#EC NOTEXT
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_returncode = 'A'.
rs_popup-cancel = abap_true.
RETURN.
ENDIF.
extract_field_values(
EXPORTING
it_fields = lt_fields
IMPORTING
ev_url = lv_url
ev_package = lv_package
ev_branch = lv_branch ).
lv_finished = abap_true.
TRY.
zcl_abapgit_url=>validate( |{ lv_url }| ).
IF iv_freeze_package = abap_false.
zcl_abapgit_repo_srv=>get_instance( )->validate_package( lv_package ).
ENDIF.
CATCH zcx_abapgit_exception INTO lx_error.
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
" in case of validation errors we display the popup again
CLEAR lv_finished.
ENDTRY.
ENDWHILE.
rs_popup-url = lv_url.
rs_popup-package = lv_package.
rs_popup-branch_name = lv_branch.
ENDMETHOD.
METHOD zif_abapgit_popups~run_page_class_popup.
DATA: lv_answer TYPE c LENGTH 1,
lt_fields TYPE TABLE OF sval.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
CLEAR: ev_name, ev_cancel.
add_field( EXPORTING iv_tabname = 'TEXTL'
iv_fieldname = 'LINE'
iv_fieldtext = 'Name'
iv_value = 'lcl_gui_page_'
CHANGING ct_fields = lt_fields ).
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
popup_title = 'Run page manually'
IMPORTING
returncode = lv_answer
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2 ##NO_TEXT.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_answer = 'A'.
ev_cancel = abap_true.
ELSE.
READ TABLE lt_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
ev_name = to_upper( <ls_field>-value ).
ENDIF.
ENDMETHOD. "run_page_class_popup
ENDCLASS.
CLASS ZCL_ABAPGIT_PASSWORD_DIALOG IMPLEMENTATION.
METHOD popup.
PERFORM password_popup
IN PROGRAM (sy-cprog)
USING iv_repo_url
CHANGING cv_user cv_pass.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_html_toolbar IMPLEMENTATION.
METHOD add.
DATA ls_item TYPE ty_item.
ASSERT iv_typ = zif_abapgit_definitions=>c_action_type-separator " sep doesn't have action
OR iv_typ = zif_abapgit_definitions=>c_action_type-onclick " click may have no action (assigned in JS)
OR iv_typ = zif_abapgit_definitions=>c_action_type-dummy " dummy may have no action
OR iv_act IS INITIAL AND io_sub IS NOT INITIAL
OR iv_act IS NOT INITIAL AND io_sub IS INITIAL. " Only one supplied
ASSERT NOT ( iv_chk <> abap_undefined AND io_sub IS NOT INITIAL ).
ls_item-txt = iv_txt.
ls_item-act = iv_act.
ls_item-ico = iv_ico.
ls_item-sub = io_sub.
ls_item-opt = iv_opt.
ls_item-typ = iv_typ.
ls_item-cur = iv_cur.
ls_item-chk = iv_chk.
ls_item-aux = iv_aux.
ls_item-id = iv_id.
APPEND ls_item TO mt_items.
ENDMETHOD. "add
METHOD constructor.
mv_id = iv_id.
ENDMETHOD. "constructor
METHOD count.
rv_count = lines( mt_items ).
ENDMETHOD.
METHOD render.
DATA: lv_class TYPE string.
CREATE OBJECT ro_html.
lv_class = 'nav-container' ##NO_TEXT.
IF iv_right = abap_true.
lv_class = lv_class && ' float-right'.
ENDIF.
ro_html->add( |<div class="{ lv_class }">| ).
ro_html->add( render_items( iv_sort = iv_sort ) ).
ro_html->add( '</div>' ).
ENDMETHOD. "render
METHOD render_as_droplist.
DATA: lv_class TYPE string.
CREATE OBJECT ro_html.
lv_class = 'nav-container' ##NO_TEXT.
IF iv_right = abap_true.
lv_class = lv_class && ' float-right'.
ENDIF.
IF iv_corner = abap_true.
lv_class = lv_class && ' corner'.
ENDIF.
ro_html->add( |<div class="{ lv_class }">| ).
ro_html->add( '<ul><li>' ).
ro_html->add_a( iv_txt = iv_label
iv_typ = zif_abapgit_definitions=>c_action_type-sapevent
iv_act = iv_action ).
ro_html->add( '<div class="minizone"></div>' ).
ro_html->add( render_items( iv_sort = iv_sort ) ).
ro_html->add( '</li></ul>' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_as_droplist
METHOD render_items.
DATA: lv_class TYPE string,
lv_icon TYPE string,
lv_id TYPE string,
lv_check TYPE string,
lv_aux TYPE string,
lv_has_icons TYPE abap_bool.
FIELD-SYMBOLS <ls_item> LIKE LINE OF mt_items.
CREATE OBJECT ro_html.
IF iv_sort = abap_true.
SORT mt_items BY txt ASCENDING AS TEXT.
ENDIF.
" Check has icons or check boxes
LOOP AT mt_items ASSIGNING <ls_item> WHERE ico IS NOT INITIAL OR chk <> abap_undefined.
lv_has_icons = abap_true.
lv_class = ' class="with-icons"'.
EXIT.
ENDLOOP.
IF mv_id IS NOT INITIAL.
lv_id = | id="{ mv_id }"|.
ENDIF.
ro_html->add( |<ul{ lv_id }{ lv_class }>| ).
" Render items
LOOP AT mt_items ASSIGNING <ls_item>.
CLEAR: lv_class, lv_icon.
IF <ls_item>-typ = zif_abapgit_definitions=>c_action_type-separator.
ro_html->add( |<li class="separator">{ <ls_item>-txt }</li>| ).
CONTINUE.
ENDIF.
IF lv_has_icons = abap_true.
IF <ls_item>-chk = abap_true.
lv_icon = zcl_abapgit_html=>icon( 'check/blue' ).
lv_check = ' data-check="X"'.
ELSEIF <ls_item>-chk = abap_false.
lv_icon = zcl_abapgit_html=>icon( 'check/grey' ).
lv_check = ' data-check=""'.
ELSE. " abap_undefined -> not a check box
lv_icon = zcl_abapgit_html=>icon( <ls_item>-ico ).
ENDIF.
ENDIF.
IF <ls_item>-cur = abap_true.
lv_class = ' class="current-menu-item"'.
ENDIF.
IF <ls_item>-aux IS NOT INITIAL.
lv_aux = | data-aux="{ <ls_item>-aux }"|.
ENDIF.
ro_html->add( |<li{ lv_class }{ lv_check }{ lv_aux }>| ).
IF <ls_item>-sub IS INITIAL.
ro_html->add_a( iv_txt = lv_icon && <ls_item>-txt
iv_typ = <ls_item>-typ
iv_act = <ls_item>-act
iv_id = <ls_item>-id
iv_opt = <ls_item>-opt ).
ELSE.
ro_html->add_a( iv_txt = lv_icon && <ls_item>-txt
iv_typ = zif_abapgit_definitions=>c_action_type-dummy
iv_act = ''
iv_id = <ls_item>-id
iv_opt = <ls_item>-opt ).
ro_html->add( <ls_item>-sub->render_items( iv_sort ) ).
ENDIF.
ro_html->add( '</li>' ).
ENDLOOP.
ro_html->add( '</ul>' ).
ENDMETHOD. "render_items
ENDCLASS.
CLASS zcl_abapgit_html_action_utils IMPLEMENTATION.
METHOD add_field.
DATA ls_field LIKE LINE OF ct_field.
FIELD-SYMBOLS <lg_src> TYPE any.
ls_field-name = iv_name.
CASE cl_abap_typedescr=>describe_by_data( ig_field )->kind.
WHEN cl_abap_typedescr=>kind_elem.
ls_field-value = ig_field.
WHEN cl_abap_typedescr=>kind_struct.
ASSIGN COMPONENT iv_name OF STRUCTURE ig_field TO <lg_src>.
ASSERT <lg_src> IS ASSIGNED.
ls_field-value = <lg_src>.
WHEN OTHERS.
ASSERT 0 = 1.
ENDCASE.
APPEND ls_field TO ct_field.
ENDMETHOD. "add_field
METHOD dbkey_decode.
DATA: lt_fields TYPE tihttpnvp.
lt_fields = parse_fields_upper_case_name( cl_http_utility=>unescape_url( |{ iv_string }| ) ).
get_field( EXPORTING iv_name = 'TYPE' it_field = lt_fields CHANGING cg_field = rs_key-type ).
get_field( EXPORTING iv_name = 'VALUE' it_field = lt_fields CHANGING cg_field = rs_key-value ).
ENDMETHOD. "dbkey_decode
METHOD dbkey_encode.
DATA: lt_fields TYPE tihttpnvp.
add_field( EXPORTING iv_name = 'TYPE' ig_field = is_key-type CHANGING ct_field = lt_fields ).
add_field( EXPORTING iv_name = 'VALUE' ig_field = is_key-value CHANGING ct_field = lt_fields ).
rv_string = cl_http_utility=>if_http_utility~fields_to_string( lt_fields ).
ENDMETHOD. "dbkey_encode
METHOD dir_decode.
DATA: lt_fields TYPE tihttpnvp.
lt_fields = parse_fields( iv_string ).
get_field( EXPORTING iv_name = 'PATH' it_field = lt_fields CHANGING cg_field = rv_path ).
ENDMETHOD. "dir_decode
METHOD dir_encode.
DATA: lt_fields TYPE tihttpnvp.
add_field( EXPORTING iv_name = 'PATH' ig_field = iv_path CHANGING ct_field = lt_fields ).
rv_string = cl_http_utility=>if_http_utility~fields_to_string( lt_fields ).
ENDMETHOD. "dir_encode
METHOD field_keys_to_upper.
FIELD-SYMBOLS <ls_field> LIKE LINE OF ct_fields.
LOOP AT ct_fields ASSIGNING <ls_field>.
<ls_field>-name = to_upper( <ls_field>-name ).
ENDLOOP.
ENDMETHOD.
METHOD file_encode.
DATA: lt_fields TYPE tihttpnvp.
add_field( EXPORTING iv_name = 'KEY' ig_field = iv_key CHANGING ct_field = lt_fields ).
add_field( EXPORTING iv_name = 'PATH' ig_field = ig_file CHANGING ct_field = lt_fields ).
add_field( EXPORTING iv_name = 'FILENAME' ig_field = ig_file CHANGING ct_field = lt_fields ).
rv_string = cl_http_utility=>if_http_utility~fields_to_string( lt_fields ).
ENDMETHOD. "file_encode
METHOD file_obj_decode.
DATA: lt_fields TYPE tihttpnvp.
ASSERT eg_file IS SUPPLIED OR eg_object IS SUPPLIED.
CLEAR: ev_key, eg_file, eg_object.
lt_fields = parse_fields_upper_case_name( iv_string ).
get_field( EXPORTING iv_name = 'KEY' it_field = lt_fields CHANGING cg_field = ev_key ).
IF eg_file IS SUPPLIED.
get_field( EXPORTING iv_name = 'PATH' it_field = lt_fields CHANGING cg_field = eg_file ).
get_field( EXPORTING iv_name = 'FILENAME' it_field = lt_fields CHANGING cg_field = eg_file ).
ENDIF.
IF eg_object IS SUPPLIED.
get_field( EXPORTING iv_name = 'OBJ_TYPE' it_field = lt_fields CHANGING cg_field = eg_object ).
get_field( EXPORTING iv_name = 'OBJ_NAME' it_field = lt_fields CHANGING cg_field = eg_object ).
ENDIF.
ENDMETHOD. "file_decode
METHOD get_field.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF it_field,
<lg_dest> TYPE any.
READ TABLE it_field ASSIGNING <ls_field> WITH KEY name = iv_name.
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
CASE cl_abap_typedescr=>describe_by_data( cg_field )->kind.
WHEN cl_abap_typedescr=>kind_elem.
cg_field = <ls_field>-value.
WHEN cl_abap_typedescr=>kind_struct.
ASSIGN COMPONENT iv_name OF STRUCTURE cg_field TO <lg_dest>.
ASSERT <lg_dest> IS ASSIGNED.
<lg_dest> = <ls_field>-value.
WHEN OTHERS.
ASSERT 0 = 1.
ENDCASE.
ENDMETHOD. "get_field
METHOD jump_decode.
DATA: lt_fields TYPE tihttpnvp.
lt_fields = parse_fields( iv_string ).
get_field( EXPORTING iv_name = 'TYPE' it_field = lt_fields CHANGING cg_field = ev_obj_type ).
get_field( EXPORTING iv_name = 'NAME' it_field = lt_fields CHANGING cg_field = ev_obj_name ).
ENDMETHOD. "jump_decode
METHOD jump_encode.
DATA: lt_fields TYPE tihttpnvp.
add_field( EXPORTING iv_name = 'TYPE' ig_field = iv_obj_type CHANGING ct_field = lt_fields ).
add_field( EXPORTING iv_name = 'NAME' ig_field = iv_obj_name CHANGING ct_field = lt_fields ).
rv_string = cl_http_utility=>if_http_utility~fields_to_string( lt_fields ).
ENDMETHOD. "jump_encode
METHOD obj_encode.
DATA: lt_fields TYPE tihttpnvp.
add_field( EXPORTING iv_name = 'KEY' ig_field = iv_key CHANGING ct_field = lt_fields ).
add_field( EXPORTING iv_name = 'OBJ_TYPE' ig_field = ig_object CHANGING ct_field = lt_fields ).
add_field( EXPORTING iv_name = 'OBJ_NAME' ig_field = ig_object CHANGING ct_field = lt_fields ).
rv_string = cl_http_utility=>if_http_utility~fields_to_string( lt_fields ).
ENDMETHOD. "obj_encode
METHOD parse_fields.
DATA: lt_substrings TYPE stringtab,
ls_field LIKE LINE OF rt_fields.
FIELD-SYMBOLS: <lv_substring> LIKE LINE OF lt_substrings.
SPLIT iv_string AT '&' INTO TABLE lt_substrings.
LOOP AT lt_substrings ASSIGNING <lv_substring>.
CLEAR: ls_field.
ls_field-name = substring_before( val = <lv_substring>
sub = '=' ).
ls_field-name = unescape( ls_field-name ).
ls_field-value = substring_after( val = <lv_substring>
sub = '=' ).
ls_field-value = unescape( ls_field-value ).
INSERT ls_field INTO TABLE rt_fields.
ENDLOOP.
ENDMETHOD.
METHOD parse_fields_upper_case_name.
rt_fields = parse_fields( iv_string ).
field_keys_to_upper( CHANGING ct_fields = rt_fields ).
ENDMETHOD. " parse_fields.
METHOD stage_decode.
DATA: lt_fields TYPE tihttpnvp.
lt_fields = parse_fields_upper_case_name( iv_getdata ).
get_field( EXPORTING iv_name = 'KEY' it_field = lt_fields CHANGING cg_field = ev_key ).
get_field( EXPORTING iv_name = 'SEED' it_field = lt_fields CHANGING cg_field = ev_seed ).
ASSERT NOT ev_key IS INITIAL.
ENDMETHOD. " stage_decode.
METHOD unescape.
rv_string = iv_string.
REPLACE ALL OCCURRENCES OF '%3F' IN rv_string WITH '?'.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_HTML IMPLEMENTATION.
METHOD a.
DATA: lv_class TYPE string,
lv_href TYPE string,
lv_click TYPE string,
lv_id TYPE string,
lv_style TYPE string,
lv_span TYPE string.
lv_class = iv_class.
IF iv_opt CA zif_abapgit_definitions=>c_html_opt-strong.
lv_class = lv_class && ' emphasis' ##NO_TEXT.
ENDIF.
IF iv_opt CA zif_abapgit_definitions=>c_html_opt-cancel.
lv_class = lv_class && ' attention' ##NO_TEXT.
ENDIF.
IF iv_opt CA zif_abapgit_definitions=>c_html_opt-crossout.
lv_class = lv_class && ' crossout grey' ##NO_TEXT.
ENDIF.
IF lv_class IS NOT INITIAL.
SHIFT lv_class LEFT DELETING LEADING space.
lv_class = | class="{ lv_class }"|.
ENDIF.
lv_href = ' href="#"'. " Default, dummy
IF iv_act IS NOT INITIAL OR iv_typ = zif_abapgit_definitions=>c_action_type-dummy.
CASE iv_typ.
WHEN zif_abapgit_definitions=>c_action_type-url.
lv_href = | href="{ iv_act }"|.
WHEN zif_abapgit_definitions=>c_action_type-sapevent.
lv_href = | href="sapevent:{ iv_act }"|.
WHEN zif_abapgit_definitions=>c_action_type-onclick.
lv_href = ' href="#"'.
lv_click = | onclick="{ iv_act }"|.
WHEN zif_abapgit_definitions=>c_action_type-dummy.
lv_href = ' href="#"'.
ENDCASE.
ENDIF.
IF iv_id IS NOT INITIAL.
lv_id = | id="{ iv_id }"|.
ENDIF.
IF iv_style IS NOT INITIAL.
lv_style = | style="{ iv_style }"|.
ENDIF.
lv_span = |<span class="tooltiptext hidden"></span>|.
rv_str = |<a{ lv_id }{ lv_class }{ lv_href }{ lv_click }{ lv_style }>{ iv_txt }{ lv_span }</a>|.
ENDMETHOD. "a
METHOD add.
DATA: lv_type TYPE c,
lo_html TYPE REF TO zcl_abapgit_html.
FIELD-SYMBOLS: <lt_tab> TYPE string_table.
DESCRIBE FIELD ig_chunk TYPE lv_type. " Describe is faster than RTTI classes
CASE lv_type.
WHEN 'C' OR 'g'. " Char or string
APPEND ig_chunk TO mt_buffer.
WHEN 'h'. " Table
ASSIGN ig_chunk TO <lt_tab>. " Assuming table of strings ! Will dump otherwise
APPEND LINES OF <lt_tab> TO mt_buffer.
WHEN 'r'. " Object ref
ASSERT ig_chunk IS BOUND. " Dev mistake
TRY.
lo_html ?= ig_chunk.
CATCH cx_sy_move_cast_error.
ASSERT 1 = 0. " Dev mistake
ENDTRY.
APPEND LINES OF lo_html->mt_buffer TO mt_buffer.
WHEN OTHERS.
ASSERT 1 = 0. " Dev mistake
ENDCASE.
ENDMETHOD. " add
METHOD add_a.
add( a( iv_txt = iv_txt
iv_act = iv_act
iv_typ = iv_typ
iv_opt = iv_opt
iv_class = iv_class
iv_id = iv_id
iv_style = iv_style ) ).
ENDMETHOD. "add_a
METHOD add_icon.
add( icon( iv_name = iv_name
iv_class = iv_class
iv_hint = iv_hint ) ).
ENDMETHOD. "add_icon
METHOD class_constructor.
CREATE OBJECT go_single_tags_re
EXPORTING
pattern = '<(AREA|BASE|BR|COL|COMMAND|EMBED|HR|IMG|INPUT|LINK|META|PARAM|SOURCE|!)'
ignore_case = abap_false.
ENDMETHOD. "class_constructor
METHOD icon.
DATA: lv_hint TYPE string,
lv_name TYPE string,
lv_color TYPE string,
lv_class TYPE string.
SPLIT iv_name AT '/' INTO lv_name lv_color.
IF iv_hint IS NOT INITIAL.
lv_hint = | title="{ iv_hint }"|.
ENDIF.
IF iv_class IS NOT INITIAL.
lv_class = | { iv_class }|.
ENDIF.
IF lv_color IS NOT INITIAL.
lv_color = | { lv_color }|.
ENDIF.
rv_str = |<i class="octicon octicon-{ lv_name }{ lv_color }{ lv_class }"{ lv_hint }></i>|.
ENDMETHOD. "icon
METHOD indent_line.
DATA: ls_study TYPE ty_study_result,
lv_x_str TYPE string.
ls_study = study_line(
is_context = cs_context
iv_line = cv_line ).
" First closing tag - shift back exceptionally
IF ( ls_study-script_close = abap_true
OR ls_study-style_close = abap_true
OR ls_study-curly_close = abap_true
OR ls_study-tag_close = abap_true )
AND cs_context-indent > 0.
lv_x_str = repeat( val = ` ` occ = ( cs_context-indent - 1 ) * c_indent_size ).
cv_line = lv_x_str && cv_line.
ELSE.
cv_line = cs_context-indent_str && cv_line.
ENDIF.
" Context status update
CASE abap_true.
WHEN ls_study-script_open.
cs_context-within_js = abap_true.
cs_context-within_style = abap_false.
WHEN ls_study-style_open.
cs_context-within_js = abap_false.
cs_context-within_style = abap_true.
WHEN ls_study-script_close OR ls_study-style_close.
cs_context-within_js = abap_false.
cs_context-within_style = abap_false.
ls_study-closings = ls_study-closings + 1.
ENDCASE.
" More-less logic chosen due to possible double tags in a line '<a><b>'
IF ls_study-openings <> ls_study-closings.
IF ls_study-openings > ls_study-closings.
cs_context-indent = cs_context-indent + 1.
ELSEIF cs_context-indent > 0. " AND ls_study-openings < ls_study-closings
cs_context-indent = cs_context-indent - 1.
ENDIF.
cs_context-indent_str = repeat( val = ` ` occ = cs_context-indent * c_indent_size ).
ENDIF.
ENDMETHOD. "indent_line
METHOD is_empty.
rv_yes = boolc( lines( mt_buffer ) = 0 ).
ENDMETHOD. "is_empty
METHOD render.
DATA: ls_context TYPE ty_indent_context,
lt_temp TYPE string_table.
FIELD-SYMBOLS: <lv_line> LIKE LINE OF lt_temp,
<lv_line_c> LIKE LINE OF lt_temp.
ls_context-no_indent_jscss = iv_no_indent_jscss.
LOOP AT mt_buffer ASSIGNING <lv_line>.
APPEND <lv_line> TO lt_temp ASSIGNING <lv_line_c>.
indent_line( CHANGING cs_context = ls_context cv_line = <lv_line_c> ).
ENDLOOP.
CONCATENATE LINES OF lt_temp INTO rv_html SEPARATED BY zif_abapgit_definitions=>c_newline.
ENDMETHOD. "render
METHOD study_line.
DATA: lv_line TYPE string,
lv_len TYPE i.
lv_line = to_upper( shift_left( val = iv_line sub = ` ` ) ).
lv_len = strlen( lv_line ).
" Some assumptions for simplification and speed
" - style & scripts tag should be opened/closed in a separate line
" - style & scripts opening and closing in one line is possible but only once
" TODO & Issues
" - What if the string IS a well formed html already not just single line ?
IF is_context-within_js = abap_true OR is_context-within_style = abap_true.
IF is_context-within_js = abap_true AND lv_len >= 8 AND lv_line(8) = '</SCRIPT'.
rs_result-script_close = abap_true.
ELSEIF is_context-within_style = abap_true AND lv_len >= 7 AND lv_line(7) = '</STYLE'.
rs_result-style_close = abap_true.
ENDIF.
IF is_context-no_indent_jscss = abap_false.
IF lv_len >= 1 AND lv_line(1) = '}'.
rs_result-curly_close = abap_true.
ENDIF.
FIND ALL OCCURRENCES OF '{' IN lv_line MATCH COUNT rs_result-openings.
FIND ALL OCCURRENCES OF '}' IN lv_line MATCH COUNT rs_result-closings.
ENDIF.
ELSE.
IF lv_len >= 7 AND lv_line(7) = '<SCRIPT'.
FIND FIRST OCCURRENCE OF '</SCRIPT' IN lv_line.
IF sy-subrc > 0. " Not found
rs_result-script_open = abap_true.
ENDIF.
ENDIF.
IF lv_len >= 6 AND lv_line(6) = '<STYLE'.
FIND FIRST OCCURRENCE OF '</STYLE' IN lv_line.
IF sy-subrc > 0. " Not found
rs_result-style_open = abap_true.
ENDIF.
ENDIF.
IF lv_len >= 2 AND lv_line(2) = '</'.
rs_result-tag_close = abap_true.
ENDIF.
FIND ALL OCCURRENCES OF '<' IN lv_line MATCH COUNT rs_result-openings.
FIND ALL OCCURRENCES OF '</' IN lv_line MATCH COUNT rs_result-closings.
FIND ALL OCCURRENCES OF REGEX go_single_tags_re IN lv_line MATCH COUNT rs_result-singles.
rs_result-openings = rs_result-openings - rs_result-closings - rs_result-singles.
ENDIF.
ENDMETHOD. "study_line
ENDCLASS.
CLASS zcl_abapgit_hotkeys IMPLEMENTATION.
METHOD get_default_hotkeys_from_pages.
DATA: lt_hotkey_actions TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action,
lo_interface TYPE REF TO cl_oo_interface,
lt_classes TYPE seo_relkeys.
FIELD-SYMBOLS: <ls_class> TYPE seorelkey.
TRY.
lo_interface ?= cl_oo_class=>get_instance( |ZIF_ABAPGIT_GUI_PAGE_HOTKEY| ).
CATCH cx_class_not_existent.
" hotkeys are only available with installed abapGit repository
RETURN.
ENDTRY.
lt_classes = lo_interface->get_implementing_classes( ).
LOOP AT lt_classes ASSIGNING <ls_class>.
CALL METHOD (<ls_class>-clsname)=>zif_abapgit_gui_page_hotkey~get_hotkey_actions
RECEIVING
rt_hotkey_actions = lt_hotkey_actions.
INSERT LINES OF lt_hotkey_actions INTO TABLE rt_hotkey_actions.
ENDLOOP.
" the global shortcuts are defined in the base class
lt_hotkey_actions = zcl_abapgit_gui_page=>get_hotkey_actions( ).
INSERT LINES OF lt_hotkey_actions INTO TABLE rt_hotkey_actions.
SORT rt_hotkey_actions.
DELETE ADJACENT DUPLICATES FROM rt_hotkey_actions.
ENDMETHOD.
METHOD get_relevant_hotkeys_for_page.
DATA: lo_settings TYPE REF TO zcl_abapgit_settings,
lv_class_name TYPE abap_abstypename,
lt_hotkey_actions_of_curr_page TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action,
lv_save_tabix TYPE syst-tabix,
lt_hotkey_actions TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action.
FIELD-SYMBOLS: <ls_hotkey> TYPE zif_abapgit_definitions=>ty_hotkey.
lo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).
rt_hotkeys = lo_settings->get_hotkeys( ).
lv_class_name = cl_abap_classdescr=>get_class_name( io_page ).
TRY.
CALL METHOD (lv_class_name)=>zif_abapgit_gui_page_hotkey~get_hotkey_actions
RECEIVING
rt_hotkey_actions = lt_hotkey_actions_of_curr_page.
CATCH cx_root.
RETURN.
ENDTRY.
" these are the global shortcuts
lt_hotkey_actions = zcl_abapgit_gui_page=>get_hotkey_actions( ).
INSERT LINES OF lt_hotkey_actions INTO TABLE lt_hotkey_actions_of_curr_page.
LOOP AT rt_hotkeys ASSIGNING <ls_hotkey>.
lv_save_tabix = sy-tabix.
READ TABLE lt_hotkey_actions_of_curr_page TRANSPORTING NO FIELDS
WITH TABLE KEY action
COMPONENTS action = <ls_hotkey>-action.
IF sy-subrc <> 0.
" We only offer hotkeys which are supported by the current page or globally
DELETE rt_hotkeys INDEX lv_save_tabix.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_VIEW_TUTORIAL IMPLEMENTATION.
METHOD render_content.
CREATE OBJECT ro_html.
ro_html->add( '<h1>Tutorial</h1>' ).
ro_html->add( '<hr>' ).
ro_html->add( '<h2>Adding and cloning repos</h2>' ).
ro_html->add( '<p><ul>' ).
ro_html->add( `<li>To clone a remote repo (e.g. from github) click ` ).
ro_html->add_a( iv_txt = '+ Online' iv_act = zif_abapgit_definitions=>c_action-repo_newonline ).
ro_html->add( ' from the top menu. This will copy a remote repo to your system.</li>' ).
ro_html->add( `<li>To add a local package as a repo click ` ).
ro_html->add_a( iv_txt = '+ Offline' iv_act = zif_abapgit_definitions=>c_action-repo_newoffline ).
ro_html->add( ' from the top menu. This will track a repo which already exist in' ).
ro_html->add( ' the system with abapGit. You''ll be able to attach it to remote origin' ).
ro_html->add( ' or just serialize as a zip file</li>' ).
ro_html->add( `<li>Go ` ).
ro_html->add_a( iv_txt = 'Explore' iv_act = zif_abapgit_definitions=>c_action-go_explore ).
ro_html->add( ' to find projects using abapGit</li>' ).
ro_html->add( '</ul></p>' ).
ro_html->add( '<h2>Repository list and favorites</h2>' ).
ro_html->add( '<p><ul>' ).
ro_html->add( |<li>To choose a repo press {
zcl_abapgit_html=>icon( 'three-bars/blue' ) } at the favorite bar.</li>| ).
ro_html->add( |<li>To favorite a repo click {
zcl_abapgit_html=>icon( 'star/darkgrey' ) } icon at repo toolbar.</li>| ).
ro_html->add( '</ul></p>' ).
ro_html->add( '<h2>abapGit repository</h2>' ).
ro_html->add( '<p><ul>' ).
ro_html->add( '<li>' ).
IF zcl_abapgit_services_abapgit=>is_installed( ) = abap_true.
ro_html->add( 'abapGit installed in package ' ).
ro_html->add( zcl_abapgit_services_abapgit=>c_package_abapgit ).
ELSE.
ro_html->add_a( iv_txt = 'install abapGit repo' iv_act = zif_abapgit_definitions=>c_action-abapgit_install ).
ro_html->add( ' - To keep abapGit up-to-date (or also to contribute) you need to' ).
ro_html->add( 'install it as a repository.' ).
ENDIF.
ro_html->add( '</li>' ).
ro_html->add( '</ul></p>' ).
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
ev_state = zif_abapgit_definitions=>c_event_state-not_handled.
ENDMETHOD.
METHOD zif_abapgit_gui_page~render.
CREATE OBJECT ro_html.
ro_html->add( '<div class="tutorial">' ).
ro_html->add( render_content( ) ).
ro_html->add( '</div>' ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_view_repo IMPLEMENTATION.
METHOD build_dir_jump_link.
DATA: lv_path TYPE string,
lv_encode TYPE string.
lv_path = iv_path.
REPLACE FIRST OCCURRENCE OF mv_cur_dir IN lv_path WITH ''.
lv_encode = zcl_abapgit_html_action_utils=>dir_encode( lv_path ).
rv_html = zcl_abapgit_html=>a( iv_txt = lv_path
iv_act = |{ c_actions-change_dir }?{ lv_encode }| ).
ENDMETHOD. "build_dir_jump_link
METHOD build_grid_menu.
CREATE OBJECT ro_toolbar.
IF mo_repo->is_offline( ) = abap_false.
ro_toolbar->add( " Show/Hide files
iv_txt = 'Show files'
iv_chk = boolc( NOT mv_hide_files = abap_true )
iv_act = c_actions-toggle_hide_files ).
ro_toolbar->add( " Show changes only
iv_txt = 'Show changes only'
iv_chk = mv_changes_only
iv_act = c_actions-toggle_changes ).
ENDIF.
ro_toolbar->add( " Show/Hide folders
iv_txt = 'Show folders'
iv_chk = mv_show_folders
iv_act = c_actions-toggle_folders ).
ENDMETHOD. "build_grid_menu
METHOD build_head_menu.
DATA: lo_tb_advanced TYPE REF TO zcl_abapgit_html_toolbar,
lo_tb_branch TYPE REF TO zcl_abapgit_html_toolbar,
lo_tb_tag TYPE REF TO zcl_abapgit_html_toolbar,
lv_key TYPE zif_abapgit_persistence=>ty_value,
lv_wp_opt LIKE zif_abapgit_definitions=>c_html_opt-crossout,
lv_crossout LIKE zif_abapgit_definitions=>c_html_opt-crossout,
lv_pull_opt LIKE zif_abapgit_definitions=>c_html_opt-crossout.
CREATE OBJECT ro_toolbar.
CREATE OBJECT lo_tb_branch.
CREATE OBJECT lo_tb_advanced.
CREATE OBJECT lo_tb_tag.
lv_key = mo_repo->get_key( ).
IF mo_repo->get_local_settings( )-write_protected = abap_true.
lv_wp_opt = zif_abapgit_definitions=>c_html_opt-crossout.
lv_pull_opt = zif_abapgit_definitions=>c_html_opt-crossout.
ELSE.
lv_pull_opt = zif_abapgit_definitions=>c_html_opt-strong.
ENDIF.
" Build branch drop-down ========================
IF mo_repo->is_offline( ) = abap_false. " Online ?
lo_tb_branch->add( iv_txt = 'Overview'
iv_act = |{ zif_abapgit_definitions=>c_action-go_branch_overview }?{ lv_key }| ).
lo_tb_branch->add( iv_txt = 'Switch'
iv_act = |{ zif_abapgit_definitions=>c_action-git_branch_switch }?{ lv_key }|
iv_opt = lv_wp_opt ).
lo_tb_branch->add( iv_txt = 'Create'
iv_act = |{ zif_abapgit_definitions=>c_action-git_branch_create }?{ lv_key }| ).
lo_tb_branch->add( iv_txt = 'Delete'
iv_act = |{ zif_abapgit_definitions=>c_action-git_branch_delete }?{ lv_key }| ).
lo_tb_tag->add( iv_txt = 'Overview'
iv_act = |{ zif_abapgit_definitions=>c_action-go_tag_overview }?{ lv_key }| ).
lo_tb_tag->add( iv_txt = 'Switch'
iv_act = |{ zif_abapgit_definitions=>c_action-git_tag_switch }?{ lv_key }|
iv_opt = lv_wp_opt ).
lo_tb_tag->add( iv_txt = 'Create'
iv_act = |{ zif_abapgit_definitions=>c_action-git_tag_create }?{ lv_key }| ).
lo_tb_tag->add( iv_txt = 'Delete'
iv_act = |{ zif_abapgit_definitions=>c_action-git_tag_delete }?{ lv_key }| ).
ENDIF.
" Build advanced drop-down ========================
IF mo_repo->is_offline( ) = abap_false. " Online ?
lo_tb_advanced->add( iv_txt = 'Reset local'
iv_act = |{ zif_abapgit_definitions=>c_action-git_reset }?{ lv_key }|
iv_opt = lv_wp_opt ).
lo_tb_advanced->add( iv_txt = 'Background mode'
iv_act = |{ zif_abapgit_definitions=>c_action-go_background }?{ lv_key }| ).
lo_tb_advanced->add( iv_txt = 'Change remote'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_remote_change }?{ lv_key }| ).
lo_tb_advanced->add( iv_txt = 'Make off-line'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_remote_detach }?{ lv_key }| ).
lo_tb_advanced->add( iv_txt = 'Force stage'
iv_act = |{ zif_abapgit_definitions=>c_action-go_stage }?{ lv_key }| ).
CLEAR lv_crossout.
IF zcl_abapgit_auth=>is_allowed( zif_abapgit_auth=>gc_authorization-transport_to_branch ) = abap_false.
lv_crossout = zif_abapgit_definitions=>c_html_opt-crossout.
ENDIF.
lo_tb_advanced->add( iv_txt = 'Transport to Branch'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_transport_to_branch }?{ lv_key }|
iv_opt = lv_crossout ).
ELSE.
lo_tb_advanced->add( iv_txt = 'Make on-line'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_remote_attach }?{ lv_key }| ).
ENDIF.
lo_tb_advanced->add( iv_txt = 'Syntax Check'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_syntax_check }?{ lv_key }| ).
lo_tb_advanced->add( iv_txt = 'Run Code Inspector'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_code_inspector }?{ lv_key }| ).
lo_tb_advanced->add( iv_txt = 'Repo settings'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_settings }?{ lv_key }| ).
CLEAR lv_crossout.
IF zcl_abapgit_auth=>is_allowed( zif_abapgit_auth=>gc_authorization-update_local_checksum ) = abap_false.
lv_crossout = zif_abapgit_definitions=>c_html_opt-crossout.
ENDIF.
lo_tb_advanced->add( iv_txt = 'Update local checksums'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_refresh_checksums }?{ lv_key }|
iv_opt = lv_crossout ).
lo_tb_advanced->add( iv_txt = 'Remove'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_remove }?{ lv_key }| ).
CLEAR lv_crossout.
IF mo_repo->get_local_settings( )-write_protected = abap_true
OR zcl_abapgit_auth=>is_allowed( zif_abapgit_auth=>gc_authorization-uninstall ) = abap_false.
lv_crossout = zif_abapgit_definitions=>c_html_opt-crossout.
ENDIF.
lo_tb_advanced->add( iv_txt = 'Uninstall'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_purge }?{ lv_key }|
iv_opt = lv_crossout ).
" Build main toolbar ==============================
IF mo_repo->is_offline( ) = abap_false. " Online ?
TRY.
IF iv_rstate IS NOT INITIAL. " Something new at remote
ro_toolbar->add( iv_txt = 'Pull'
iv_act = |{ zif_abapgit_definitions=>c_action-git_pull }?{ lv_key }|
iv_opt = lv_pull_opt ).
ENDIF.
IF iv_lstate IS NOT INITIAL. " Something new at local
ro_toolbar->add( iv_txt = 'Stage'
iv_act = |{ zif_abapgit_definitions=>c_action-go_stage }?{ lv_key }|
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ).
ENDIF.
IF iv_rstate IS NOT INITIAL OR iv_lstate IS NOT INITIAL. " Any changes
ro_toolbar->add( iv_txt = 'Show diff'
iv_act = |{ zif_abapgit_definitions=>c_action-go_diff }?key={ lv_key }|
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ).
ENDIF.
CATCH zcx_abapgit_exception ##NO_HANDLER.
" authorization error or repository does not exist
" ignore error
ENDTRY.
ro_toolbar->add( iv_txt = 'Branch'
io_sub = lo_tb_branch ) ##NO_TEXT.
ro_toolbar->add( iv_txt = 'Tag'
io_sub = lo_tb_tag ) ##NO_TEXT.
ELSE.
ro_toolbar->add( iv_txt = 'Import ZIP'
iv_act = |{ zif_abapgit_definitions=>c_action-zip_import }?{ lv_key }|
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ).
ro_toolbar->add( iv_txt = 'Export ZIP'
iv_act = |{ zif_abapgit_definitions=>c_action-zip_export }?{ lv_key }|
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ).
ENDIF.
ro_toolbar->add( iv_txt = 'Advanced'
io_sub = lo_tb_advanced ) ##NO_TEXT.
ro_toolbar->add( iv_txt = 'Refresh'
iv_act = |{ zif_abapgit_definitions=>c_action-repo_refresh }?{ lv_key }| ).
ro_toolbar->add( iv_txt = zcl_abapgit_html=>icon( iv_name = 'settings/grey70' )
io_sub = build_grid_menu( ) ).
ENDMETHOD. "build_head_menu
METHOD build_obj_jump_link.
DATA: lv_encode TYPE string.
lv_encode = zcl_abapgit_html_action_utils=>jump_encode( iv_obj_type = is_item-obj_type
iv_obj_name = is_item-obj_name ).
rv_html = zcl_abapgit_html=>a( iv_txt = |{ is_item-obj_name }|
iv_act = |{ zif_abapgit_definitions=>c_action-jump }?{ lv_encode }| ).
ENDMETHOD. "build_obj_jump_link
METHOD constructor.
DATA lo_settings TYPE REF TO zcl_abapgit_settings.
super->constructor( ).
mo_repo = zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
mv_cur_dir = '/'. " Root
mv_hide_files = zcl_abapgit_persistence_user=>get_instance( )->get_hide_files( ).
mv_changes_only = zcl_abapgit_persistence_user=>get_instance( )->get_changes_only( ).
" Read global settings to get max # of objects to be listed
lo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).
mv_max_lines = lo_settings->get_max_lines( ).
mv_max_setting = mv_max_lines.
ENDMETHOD. "constructor
METHOD get_item_class.
DATA lt_class TYPE TABLE OF string.
IF is_item-is_dir = abap_true.
APPEND 'folder' TO lt_class.
ELSEIF is_item-changes > 0.
APPEND 'modified' TO lt_class.
ELSEIF is_item-obj_name IS INITIAL.
APPEND 'unsupported' TO lt_class.
ENDIF.
IF lines( lt_class ) > 0.
rv_html = | class="{ concat_lines_of( table = lt_class sep = ` ` ) }"|.
ENDIF.
ENDMETHOD. "get_item_class
METHOD get_item_icon.
CASE is_item-obj_type.
WHEN 'PROG' OR 'CLAS' OR 'FUGR'.
rv_html = zcl_abapgit_html=>icon( 'file-code/darkgrey' ).
WHEN 'W3MI' OR 'W3HT'.
rv_html = zcl_abapgit_html=>icon( 'file-binary/darkgrey' ).
WHEN ''.
rv_html = space. " no icon
WHEN OTHERS.
rv_html = zcl_abapgit_html=>icon( 'file/darkgrey' ).
ENDCASE.
IF is_item-is_dir = abap_true.
rv_html = zcl_abapgit_html=>icon( 'file-directory/darkgrey' ).
ENDIF.
ENDMETHOD. "get_item_icon
METHOD render_empty_package.
DATA: lv_text TYPE string.
IF mv_changes_only = abap_true.
lv_text = |No changes|.
ELSE.
lv_text = |Empty package|.
ENDIF.
rv_html = |<tr class="unsupported"><td class="paddings">|
&& | <center>{ lv_text }</center>|
&& |</td></tr>|.
ENDMETHOD. "render_empty_package
METHOD render_head_line.
DATA lo_toolbar TYPE REF TO zcl_abapgit_html_toolbar.
CREATE OBJECT ro_html.
lo_toolbar = build_head_menu( iv_lstate = iv_lstate iv_rstate = iv_rstate ).
ro_html->add( '<div class="paddings">' ).
ro_html->add( '<table class="w100"><tr>' ).
IF mv_show_folders = abap_true.
ro_html->add( |<td class="current_dir">{ mv_cur_dir }</td>| ).
ENDIF.
ro_html->add( '<td class="right">' ).
ro_html->add( lo_toolbar->render( iv_right = abap_true ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr></table>' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_head_line
METHOD render_item.
DATA: lv_link TYPE string.
CREATE OBJECT ro_html.
ro_html->add( |<tr{ get_item_class( is_item ) }>| ).
IF is_item-obj_name IS INITIAL AND is_item-is_dir = abap_false.
ro_html->add( '<td colspan="2"></td>'
&& '<td class="object">'
&& '<i class="grey">non-code and meta files</i>'
&& '</td>' ).
ELSE.
ro_html->add( |<td class="icon">{ get_item_icon( is_item ) }</td>| ).
IF is_item-is_dir = abap_true. " Subdir
lv_link = build_dir_jump_link( is_item-path ).
ro_html->add( |<td class="dir" colspan="2">{ lv_link }</td>| ).
ELSE.
lv_link = build_obj_jump_link( is_item ).
ro_html->add( |<td class="type">{ is_item-obj_type }</td>| ).
ro_html->add( |<td class="object">{ lv_link }</td>| ).
ENDIF.
ENDIF.
IF mo_repo->is_offline( ) = abap_false.
" Files
ro_html->add( '<td class="files">' ).
ro_html->add( render_item_files( is_item ) ).
ro_html->add( '</td>' ).
" Command
ro_html->add( '<td class="cmd">' ).
ro_html->add( render_item_command( is_item ) ).
ro_html->add( '</td>' ).
ENDIF.
ro_html->add( '</tr>' ).
ENDMETHOD. "render_item
METHOD render_item_command.
DATA: lv_difflink TYPE string,
ls_file LIKE LINE OF is_item-files.
CREATE OBJECT ro_html.
IF is_item-is_dir = abap_true. " Directory
ro_html->add( '<div>' ).
ro_html->add( |<span class="grey">{ is_item-changes } changes</span>| ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_item_state( iv_lstate = is_item-lstate
iv_rstate = is_item-rstate ) ).
ro_html->add( '</div>' ).
ELSEIF is_item-changes > 0.
IF mv_hide_files = abap_true AND is_item-obj_name IS NOT INITIAL.
lv_difflink = zcl_abapgit_html_action_utils=>obj_encode(
iv_key = mo_repo->get_key( )
ig_object = is_item ).
ro_html->add( '<div>' ).
ro_html->add_a( iv_txt = |view diff ({ is_item-changes })|
iv_act = |{ zif_abapgit_definitions=>c_action-go_diff }?{ lv_difflink }| ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_item_state( iv_lstate = is_item-lstate
iv_rstate = is_item-rstate ) ).
ro_html->add( '</div>' ).
ELSE.
LOOP AT is_item-files INTO ls_file.
ro_html->add( '<div>' ).
IF ls_file-is_changed = abap_true.
lv_difflink = zcl_abapgit_html_action_utils=>file_encode(
iv_key = mo_repo->get_key( )
ig_file = ls_file ).
ro_html->add_a( iv_txt = 'view diff'
iv_act = |{ zif_abapgit_definitions=>c_action-go_diff }?{ lv_difflink }| ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_item_state( iv_lstate = ls_file-lstate
iv_rstate = ls_file-rstate ) ).
ELSE.
ro_html->add( ' ' ).
ENDIF.
ro_html->add( '</div>' ).
ENDLOOP.
ENDIF.
ENDIF.
ENDMETHOD. "render_item_command
METHOD render_item_files.
DATA: ls_file LIKE LINE OF is_item-files.
CREATE OBJECT ro_html.
IF mv_hide_files = abap_true AND is_item-obj_type IS NOT INITIAL.
RETURN.
ENDIF.
LOOP AT is_item-files INTO ls_file.
ro_html->add( |<div>{ ls_file-path && ls_file-filename }</div>| ).
ENDLOOP.
ENDMETHOD. "render_item_files
METHOD render_parent_dir.
CREATE OBJECT ro_html.
ro_html->add( '<tr class="folder">' ).
ro_html->add( |<td class="icon">{ zcl_abapgit_html=>icon( 'dir' ) }</td>| ).
ro_html->add( |<td class="object" colspan="2">{ build_dir_jump_link( '..' ) }</td>| ).
IF mo_repo->is_offline( ) = abap_false.
ro_html->add( |<td colspan="2"></td>| ). " Dummy for online
ENDIF.
ro_html->add( '</tr>' ).
ENDMETHOD. "render_parent_dir
METHOD zif_abapgit_gui_page~on_event.
DATA: lv_path TYPE string.
CASE iv_action.
WHEN c_actions-toggle_hide_files. " Toggle file diplay
mv_hide_files = zcl_abapgit_persistence_user=>get_instance( )->toggle_hide_files( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_actions-change_dir. " Change dir
lv_path = zcl_abapgit_html_action_utils=>dir_decode( iv_getdata ).
mv_cur_dir = zcl_abapgit_path=>change_dir( iv_cur_dir = mv_cur_dir iv_cd = lv_path ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_actions-toggle_folders. " Toggle folder view
mv_show_folders = boolc( mv_show_folders <> abap_true ).
mv_cur_dir = '/'. " Root
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_actions-toggle_changes. " Toggle changes only view
mv_changes_only = zcl_abapgit_persistence_user=>get_instance( )->toggle_changes_only( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_actions-display_more. " Increase MAX lines limit
mv_max_lines = mv_max_lines + mv_max_setting.
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
ENDCASE.
ENDMETHOD. "lif_gui_page~on_event
METHOD zif_abapgit_gui_page~render.
DATA: lt_repo_items TYPE zif_abapgit_definitions=>tt_repo_items,
lo_browser TYPE REF TO zcl_abapgit_repo_content_list,
lx_error TYPE REF TO zcx_abapgit_exception,
lv_lstate TYPE char1,
lv_rstate TYPE char1,
lv_max TYPE abap_bool,
lv_max_str TYPE string,
lv_add_str TYPE string,
lo_log TYPE REF TO zcl_abapgit_log.
FIELD-SYMBOLS <ls_item> LIKE LINE OF lt_repo_items.
" Reinit, for the case of type change
mo_repo = zcl_abapgit_repo_srv=>get_instance( )->get( mo_repo->get_key( ) ).
CREATE OBJECT ro_html.
TRY.
CREATE OBJECT lo_browser
EXPORTING
io_repo = mo_repo.
lt_repo_items = lo_browser->list( iv_path = mv_cur_dir
iv_by_folders = mv_show_folders
iv_changes_only = mv_changes_only ).
LOOP AT lt_repo_items ASSIGNING <ls_item>.
zcl_abapgit_state=>reduce( EXPORTING iv_cur = <ls_item>-lstate
CHANGING cv_prev = lv_lstate ).
zcl_abapgit_state=>reduce( EXPORTING iv_cur = <ls_item>-rstate
CHANGING cv_prev = lv_rstate ).
ENDLOOP.
ro_html->add( render_head_line( iv_lstate = lv_lstate
iv_rstate = lv_rstate ) ).
lo_log = lo_browser->get_log( ).
IF mo_repo->is_offline( ) = abap_false AND lo_log->count( ) > 0.
ro_html->add( '<div class="log">' ).
ro_html->add( lo_log->to_html( ) ). " shows eg. list of unsupported objects
ro_html->add( '</div>' ).
ENDIF.
ro_html->add( '<div class="repo_container">' ).
" Repo content table
ro_html->add( '<table class="repo_tab">' ).
IF zcl_abapgit_path=>is_root( mv_cur_dir ) = abap_false.
ro_html->add( render_parent_dir( ) ).
ENDIF.
IF lines( lt_repo_items ) = 0.
ro_html->add( render_empty_package( ) ).
ELSE.
LOOP AT lt_repo_items ASSIGNING <ls_item>.
IF mv_max_lines > 0 AND sy-tabix > mv_max_lines.
lv_max = abap_true.
EXIT. " current loop
ENDIF.
ro_html->add( render_item( <ls_item> ) ).
ENDLOOP.
ENDIF.
ro_html->add( '</table>' ).
IF lv_max = abap_true.
ro_html->add( '<div class = "dummydiv">' ).
IF mv_max_lines = 1.
lv_max_str = '1 object'.
ELSE.
lv_max_str = |first { mv_max_lines } objects|.
ENDIF.
lv_add_str = |+{ mv_max_setting }|.
ro_html->add( |Only { lv_max_str } shown in list. Display {
zcl_abapgit_html=>a( iv_txt = lv_add_str iv_act = c_actions-display_more )
} more. (Set in Advanced > {
zcl_abapgit_html=>a( iv_txt = 'Settings' iv_act = zif_abapgit_definitions=>c_action-go_settings )
} )| ).
ro_html->add( '</div>' ).
ENDIF.
ro_html->add( '</div>' ).
CATCH zcx_abapgit_exception INTO lx_error.
ro_html->add( render_head_line( iv_lstate = lv_lstate iv_rstate = lv_rstate ) ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_error( ix_error = lx_error ) ).
ENDTRY.
ENDMETHOD. "lif_gui_page~render
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_ROUTER IMPLEMENTATION.
METHOD get_page_background.
CREATE OBJECT ri_page TYPE zcl_abapgit_gui_page_bkg
EXPORTING
iv_key = iv_key.
ENDMETHOD.
METHOD get_page_branch_overview.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
lo_page TYPE REF TO zcl_abapgit_gui_page_boverview,
lv_key TYPE zif_abapgit_persistence=>ty_repo-key.
lv_key = iv_getdata.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( lv_key ).
CREATE OBJECT lo_page
EXPORTING
io_repo = lo_repo.
ri_page = lo_page.
ENDMETHOD.
METHOD get_page_diff.
DATA: ls_file TYPE zif_abapgit_definitions=>ty_file,
ls_object TYPE zif_abapgit_definitions=>ty_item,
lo_page TYPE REF TO zcl_abapgit_gui_page_diff,
lv_key TYPE zif_abapgit_persistence=>ty_repo-key.
zcl_abapgit_html_action_utils=>file_obj_decode(
EXPORTING
iv_string = iv_getdata
IMPORTING
ev_key = lv_key
eg_file = ls_file
eg_object = ls_object ).
CREATE OBJECT lo_page
EXPORTING
iv_key = lv_key
is_file = ls_file
is_object = ls_object.
ri_page = lo_page.
ENDMETHOD.
METHOD get_page_playground.
DATA: lv_class_name TYPE string,
lv_cancel TYPE abap_bool,
li_popups TYPE REF TO zif_abapgit_popups.
li_popups = zcl_abapgit_ui_factory=>get_popups( ).
li_popups->run_page_class_popup(
IMPORTING
ev_name = lv_class_name
ev_cancel = lv_cancel ).
IF lv_cancel = abap_true.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
TRY.
CREATE OBJECT ri_page TYPE (lv_class_name).
CATCH cx_sy_create_object_error.
zcx_abapgit_exception=>raise( |Cannot create page class { lv_class_name }| ).
ENDTRY.
ENDMETHOD.
METHOD get_page_stage.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
lv_key TYPE zif_abapgit_persistence=>ty_repo-key,
lv_seed TYPE string,
lo_stage_page TYPE REF TO zcl_abapgit_gui_page_stage,
lo_code_inspector_page TYPE REF TO zcl_abapgit_gui_page_code_insp.
FIND FIRST OCCURRENCE OF '=' IN iv_getdata.
IF sy-subrc <> 0. " Not found ? -> just repo key in params
lv_key = iv_getdata.
ELSE.
zcl_abapgit_html_action_utils=>stage_decode(
EXPORTING iv_getdata = iv_getdata
IMPORTING ev_key = lv_key
ev_seed = lv_seed ).
ENDIF.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( lv_key ).
IF lo_repo->get_local_settings( )-code_inspector_check_variant IS NOT INITIAL.
CREATE OBJECT lo_code_inspector_page
EXPORTING
io_repo = lo_repo.
ri_page = lo_code_inspector_page.
ELSE.
" force refresh on stage, to make sure the latest local and remote files are used
lo_repo->refresh( ).
CREATE OBJECT lo_stage_page
EXPORTING
io_repo = lo_repo
iv_seed = lv_seed.
ri_page = lo_stage_page.
ENDIF.
ENDMETHOD.
METHOD on_event.
DATA: lv_url TYPE string,
lv_key TYPE zif_abapgit_persistence=>ty_repo-key,
ls_item TYPE zif_abapgit_definitions=>ty_item.
lv_key = iv_getdata. " TODO refactor
lv_url = iv_getdata. " TODO refactor
CASE iv_action.
" General PAGE routing
WHEN zif_abapgit_definitions=>c_action-go_main. " Go Main page
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_main.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_explore. " Go Explore page
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_explore.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_repo_overview. " Go Repository overview
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_repo_over.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_db. " Go DB util page
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_db.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_debuginfo.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_debuginfo.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_settings.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_settings.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_background_run. " Go background run page
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_bkg_run.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_background. " Go Background page
ei_page = get_page_background( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_diff. " Go Diff page
ei_page = get_page_diff(
iv_getdata = iv_getdata
iv_prev_page = iv_prev_page ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page_w_bookmark.
WHEN zif_abapgit_definitions=>c_action-go_stage. " Go Staging page
ei_page = get_page_stage( iv_getdata ).
IF iv_prev_page = 'PAGE_DIFF'.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
ELSE.
ev_state = zif_abapgit_definitions=>c_event_state-new_page_w_bookmark.
ENDIF.
WHEN zif_abapgit_definitions=>c_action-go_branch_overview. " Go repo branch overview
ei_page = get_page_branch_overview( iv_getdata ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_playground. " Create playground page
ei_page = get_page_playground( ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-go_tutorial. " Go to tutorial
zcl_abapgit_persistence_user=>get_instance( )->set_repo_show( '' ). " Clear show_id
ev_state = zif_abapgit_definitions=>c_event_state-re_render. " Assume we are on main page
" SAP GUI actions
WHEN zif_abapgit_definitions=>c_action-jump. " Open object editor
zcl_abapgit_html_action_utils=>jump_decode(
EXPORTING iv_string = iv_getdata
IMPORTING ev_obj_type = ls_item-obj_type
ev_obj_name = ls_item-obj_name ).
zcl_abapgit_objects=>jump( ls_item ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN zif_abapgit_definitions=>c_action-jump_pkg. " Open SE80
zcl_abapgit_services_repo=>open_se80( |{ iv_getdata }| ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
" DB actions
WHEN zif_abapgit_definitions=>c_action-db_edit.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_db_edit
EXPORTING
is_key = zcl_abapgit_html_action_utils=>dbkey_decode( iv_getdata ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
IF iv_prev_page = 'PAGE_DB_DIS'.
ev_state = zif_abapgit_definitions=>c_event_state-new_page_replacing.
ENDIF.
WHEN zif_abapgit_definitions=>c_action-db_display.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_db_dis
EXPORTING
is_key = zcl_abapgit_html_action_utils=>dbkey_decode( iv_getdata ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
" ABAPGIT services actions
WHEN zif_abapgit_definitions=>c_action-abapgit_home. " Go abapGit homepage
zcl_abapgit_services_abapgit=>open_abapgit_homepage( ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN zif_abapgit_definitions=>c_action-abapgit_install. " Install abapGit
zcl_abapgit_services_abapgit=>install_abapgit( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
" REPOSITORY services actions
WHEN zif_abapgit_definitions=>c_action-repo_newoffline. " New offline repo
zcl_abapgit_services_repo=>new_offline( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_refresh. " Repo refresh
zcl_abapgit_services_repo=>refresh( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_syntax_check.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_syntax
EXPORTING
io_repo = zcl_abapgit_repo_srv=>get_instance( )->get( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-repo_code_inspector.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_code_insp
EXPORTING
io_repo = zcl_abapgit_repo_srv=>get_instance( )->get( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-repo_purge. " Repo remove & purge all objects
zcl_abapgit_services_repo=>purge( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_remove. " Repo remove
zcl_abapgit_services_repo=>remove( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_newonline.
zcl_abapgit_services_repo=>new_online( lv_url ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN 'install'. " 'install' is for explore page
zcl_abapgit_services_repo=>new_online( lv_url ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_refresh_checksums. " Rebuil local checksums
zcl_abapgit_services_repo=>refresh_local_checksums( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_toggle_fav. " Toggle repo as favorite
zcl_abapgit_services_repo=>toggle_favorite( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_transport_to_branch.
zcl_abapgit_services_repo=>transport_to_branch( iv_repository_key = lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_settings.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_repo_sett
EXPORTING
io_repo = zcl_abapgit_repo_srv=>get_instance( )->get( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
" ZIP services actions
WHEN zif_abapgit_definitions=>c_action-zip_import. " Import repo from ZIP
zcl_abapgit_zip=>import( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-zip_export. " Export repo as ZIP
zcl_abapgit_zip=>export( zcl_abapgit_repo_srv=>get_instance( )->get( lv_key ) ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN zif_abapgit_definitions=>c_action-zip_package. " Export package as ZIP
zcl_abapgit_zip=>export_package( ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN zif_abapgit_definitions=>c_action-zip_transport. " Export transport as ZIP
zcl_abapgit_transport=>zip( ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN zif_abapgit_definitions=>c_action-zip_object. " Export object as ZIP
zcl_abapgit_zip=>export_object( ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
" Remote ORIGIN manipulations
WHEN zif_abapgit_definitions=>c_action-repo_remote_attach. " Remote attach
zcl_abapgit_services_repo=>remote_attach( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_remote_detach. " Remote detach
zcl_abapgit_services_repo=>remote_detach( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-repo_remote_change. " Remote change
zcl_abapgit_services_repo=>remote_change( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
" GIT actions
WHEN zif_abapgit_definitions=>c_action-git_pull. " GIT Pull
zcl_abapgit_services_git=>pull( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-git_reset. " GIT Reset
zcl_abapgit_services_git=>reset( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-git_branch_create. " GIT Create new branch
zcl_abapgit_services_git=>create_branch( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-git_branch_delete. " GIT Delete remote branch
zcl_abapgit_services_git=>delete_branch( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-git_branch_switch. " GIT Switch branch
zcl_abapgit_services_git=>switch_branch( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-go_tag_overview. " GIT Tag overview
zcl_abapgit_services_git=>tag_overview( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-git_tag_create. " GIT Tag create
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_tag
EXPORTING
io_repo = zcl_abapgit_repo_srv=>get_instance( )->get( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN zif_abapgit_definitions=>c_action-git_tag_delete. " GIT Tag create
zcl_abapgit_services_git=>delete_tag( lv_key ).
zcl_abapgit_services_repo=>refresh( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN zif_abapgit_definitions=>c_action-git_tag_switch. " GIT Switch Tag
zcl_abapgit_services_git=>switch_tag( lv_key ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
"Others
WHEN OTHERS.
ev_state = zif_abapgit_definitions=>c_event_state-not_handled.
ENDCASE.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page_tag IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
mo_repo_online ?= io_repo.
ms_control-page_title = 'TAG'.
mv_selected_type = c_tag_type-lightweight.
ENDMETHOD.
METHOD create_tag.
DATA:
ls_tag TYPE zif_abapgit_definitions=>ty_git_tag,
lx_error TYPE REF TO zcx_abapgit_exception,
lv_text TYPE string.
parse_tag_request(
EXPORTING it_postdata = it_postdata
IMPORTING eg_fields = ls_tag ).
IF ls_tag-name IS INITIAL.
zcx_abapgit_exception=>raise( |Please supply a tag name| ).
ENDIF.
ls_tag-name = zcl_abapgit_tag=>add_tag_prefix( ls_tag-name ).
ASSERT ls_tag-name CP 'refs/tags/+*'.
CASE mv_selected_type.
WHEN c_tag_type-lightweight.
ls_tag-type = zif_abapgit_definitions=>c_git_branch_type-lightweight_tag.
WHEN c_tag_type-annotated.
ls_tag-type = zif_abapgit_definitions=>c_git_branch_type-annotated_tag.
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Invalid tag type: { mv_selected_type }| ).
ENDCASE.
TRY.
zcl_abapgit_git_porcelain=>create_tag( iv_url = mo_repo_online->get_url( )
is_tag = ls_tag ).
CATCH zcx_abapgit_exception INTO lx_error.
zcx_abapgit_exception=>raise( |Cannot create tag { ls_tag-name }. Error: '{ lx_error->get_text( ) }'| ).
ENDTRY.
IF ls_tag-type = zif_abapgit_definitions=>c_git_branch_type-lightweight_tag.
lv_text = |Lightweight tag { zcl_abapgit_tag=>remove_tag_prefix( ls_tag-name ) } created| ##NO_TEXT.
ELSEIF ls_tag-type = zif_abapgit_definitions=>c_git_branch_type-annotated_tag.
lv_text = |Annotated tag { zcl_abapgit_tag=>remove_tag_prefix( ls_tag-name ) } created| ##NO_TEXT.
ENDIF.
MESSAGE lv_text TYPE 'S'.
ENDMETHOD.
METHOD parse_change_tag_type_request.
FIELD-SYMBOLS: <lv_postdata> TYPE cnht_post_data_line.
READ TABLE it_postdata ASSIGNING <lv_postdata>
INDEX 1.
IF sy-subrc = 0.
FIND FIRST OCCURRENCE OF REGEX `type=(.*)`
IN <lv_postdata>
SUBMATCHES mv_selected_type.
ENDIF.
mv_selected_type = condense( mv_selected_type ).
ENDMETHOD.
METHOD parse_tag_request.
CONSTANTS: lc_replace TYPE string VALUE '<<new>>'.
DATA: lv_string TYPE string,
lt_fields TYPE tihttpnvp.
FIELD-SYMBOLS <lv_body> TYPE string.
CLEAR eg_fields.
CONCATENATE LINES OF it_postdata INTO lv_string.
REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_crlf IN lv_string WITH lc_replace.
REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_newline IN lv_string WITH lc_replace.
lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( lv_string ).
zcl_abapgit_html_action_utils=>get_field( EXPORTING iv_name = 'SHA1'
it_field = lt_fields
CHANGING cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field( EXPORTING iv_name = 'NAME'
it_field = lt_fields
CHANGING cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field( EXPORTING iv_name = 'TAGGER_NAME'
it_field = lt_fields
CHANGING cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field( EXPORTING iv_name = 'TAGGER_EMAIL'
it_field = lt_fields
CHANGING cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field( EXPORTING iv_name = 'MESSAGE'
it_field = lt_fields
CHANGING cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field( EXPORTING iv_name = 'BODY'
it_field = lt_fields
CHANGING cg_field = eg_fields ).
ASSIGN COMPONENT 'BODY' OF STRUCTURE eg_fields TO <lv_body>.
ASSERT <lv_body> IS ASSIGNED.
REPLACE ALL OCCURRENCES OF lc_replace IN <lv_body> WITH zif_abapgit_definitions=>c_newline.
ENDMETHOD.
METHOD render_content.
CREATE OBJECT ro_html.
ro_html->add( '<div class="repo">' ).
ro_html->add( render_menu( ) ).
ro_html->add( render_form( ) ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD render_form.
CONSTANTS: lc_body_col_max TYPE i VALUE 150.
DATA: li_user TYPE REF TO zif_abapgit_persist_user,
lv_user TYPE string,
lv_email TYPE string,
lv_s_param TYPE string,
lo_settings TYPE REF TO zcl_abapgit_settings,
lv_body_size TYPE i,
lt_type TYPE stringtab,
lv_selected TYPE string.
FIELD-SYMBOLS: <lv_type> LIKE LINE OF lt_type.
li_user = zcl_abapgit_persistence_user=>get_instance( ).
lv_user = li_user->get_repo_git_user_name( mo_repo_online->get_url( ) ).
IF lv_user IS INITIAL.
lv_user = li_user->get_default_git_user_name( ).
ENDIF.
IF lv_user IS INITIAL.
" get default from user master record
lv_user = zcl_abapgit_user_master_record=>get_instance( sy-uname )->get_name( ).
ENDIF.
lv_email = li_user->get_repo_git_user_email( mo_repo_online->get_url( ) ).
IF lv_email IS INITIAL.
lv_email = li_user->get_default_git_user_email( ).
ENDIF.
IF lv_email IS INITIAL.
" get default from user master record
lv_email = zcl_abapgit_user_master_record=>get_instance( sy-uname )->get_email( ).
ENDIF.
CREATE OBJECT ro_html.
ro_html->add( '<div class="form-container">' ).
ro_html->add( '<form id="commit_form" class="aligned-form grey70"'
&& ' method="post" action="sapevent:commit_post">' ).
INSERT c_tag_type-lightweight
INTO TABLE lt_type.
INSERT c_tag_type-annotated
INTO TABLE lt_type.
ro_html->add( '<div class="row">' ).
ro_html->add( 'Tag type <select name="folder_logic" onchange="onTagTypeChange(this)">' ).
LOOP AT lt_type ASSIGNING <lv_type>.
IF mv_selected_type = <lv_type>.
lv_selected = 'selected'.
ELSE.
CLEAR: lv_selected.
ENDIF.
ro_html->add( |<option value="{ <lv_type> }" |
&& |{ lv_selected }>|
&& |{ <lv_type> }</option>| ).
ENDLOOP.
ro_html->add( '</div>' ).
ro_html->add( '</select>' ).
ro_html->add( '<br>' ).
ro_html->add( '<br>' ).
ro_html->add( render_text_input( iv_name = 'sha1'
iv_label = 'SHA1'
iv_value = mo_repo_online->get_sha1_remote( ) ) ).
ro_html->add( render_text_input( iv_name = 'name'
iv_label = 'tag name' ) ).
IF mv_selected_type = c_tag_type-annotated.
ro_html->add( render_text_input( iv_name = 'tagger_name'
iv_label = 'tagger name'
iv_value = lv_user ) ).
ro_html->add( render_text_input( iv_name = 'tagger_email'
iv_label = 'tagger e-mail'
iv_value = lv_email ) ).
lo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).
lv_s_param = lo_settings->get_commitmsg_comment_length( ).
ro_html->add( render_text_input( iv_name = 'message'
iv_label = 'message'
iv_max_length = lv_s_param ) ).
ro_html->add( '<div class="row">' ).
ro_html->add( '<label for="c-body">body</label>' ).
lv_body_size = lo_settings->get_commitmsg_body_size( ).
IF lv_body_size > lc_body_col_max.
lv_body_size = lc_body_col_max.
ENDIF.
ro_html->add( |<textarea id="c-body" name="body" rows="10" cols="| &&
|{ lv_body_size }"></textarea>| ).
ENDIF.
ro_html->add( '<input type="submit" class="hidden-submit">' ).
ro_html->add( '</div>' ).
ro_html->add( '</form>' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_form
METHOD render_menu.
DATA lo_toolbar TYPE REF TO zcl_abapgit_html_toolbar.
CREATE OBJECT ro_html.
CREATE OBJECT lo_toolbar.
lo_toolbar->add( iv_act = 'submitFormById(''commit_form'');'
iv_txt = 'Create'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ) ##NO_TEXT.
lo_toolbar->add( iv_act = c_action-commit_cancel
iv_txt = 'Cancel'
iv_opt = zif_abapgit_definitions=>c_html_opt-cancel ) ##NO_TEXT.
ro_html->add( '<div class="paddings">' ).
ro_html->add( lo_toolbar->render( ) ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_menu
METHOD render_text_input.
DATA lv_attrs TYPE string.
CREATE OBJECT ro_html.
IF iv_value IS NOT INITIAL.
lv_attrs = | value="{ iv_value }"|.
ENDIF.
IF iv_max_length IS NOT INITIAL.
lv_attrs = | maxlength="{ iv_max_length }"|.
ENDIF.
ro_html->add( '<div class="row">' ).
ro_html->add( |<label for="{ iv_name }">{ iv_label }</label>| ).
ro_html->add( |<input id="{ iv_name }" name="{ iv_name }" type="text"{ lv_attrs }>| ).
ro_html->add( '</div>' ).
ENDMETHOD. " render_text_input
METHOD scripts.
ro_html = super->scripts( ).
ro_html->add( 'setInitialFocus("name");' ).
ENDMETHOD. "scripts
METHOD zif_abapgit_gui_page~on_event.
CASE iv_action.
WHEN c_action-commit_post.
create_tag( it_postdata ).
ev_state = zif_abapgit_definitions=>c_event_state-go_back.
WHEN c_action-change_tag_type.
parse_change_tag_type_request( it_postdata ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_action-commit_cancel.
ev_state = zif_abapgit_definitions=>c_event_state-go_back.
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_SYNTAX IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
ms_control-page_title = 'SYNTAX CHECK'.
mo_repo = io_repo.
ENDMETHOD. " constructor.
METHOD render_content.
DATA: li_syntax_check TYPE REF TO zif_abapgit_code_inspector,
lt_result TYPE scit_alvlist,
ls_result LIKE LINE OF lt_result.
li_syntax_check = zcl_abapgit_factory=>get_syntax_check( iv_package = mo_repo->get_package( ) ).
lt_result = li_syntax_check->run( ).
CREATE OBJECT ro_html.
ro_html->add( '<div class="toc">' ).
IF lines( lt_result ) = 0.
ro_html->add( 'No errors' ).
ENDIF.
LOOP AT lt_result INTO ls_result.
ro_html->add( |{ ls_result-objtype } { ls_result-objname } { ls_result-kind } { ls_result-text }<br>| ).
ENDLOOP.
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_STAGE IMPLEMENTATION.
METHOD build_menu.
CREATE OBJECT ro_menu.
IF lines( ms_files-local ) > 0.
ro_menu->add( iv_txt = |All diffs|
iv_act = |{ zif_abapgit_definitions=>c_action-go_diff }?key={ mo_repo->get_key( ) }| ).
ENDIF.
ENDMETHOD. "build_menu
METHOD constructor.
DATA lv_ts TYPE timestamp.
super->constructor( ).
ms_control-page_title = 'STAGE'.
mo_repo = io_repo.
ms_files = zcl_abapgit_stage_logic=>get( mo_repo ).
mv_seed = iv_seed.
IF mv_seed IS INITIAL. " Generate based on time unless obtained from diff page
GET TIME STAMP FIELD lv_ts.
mv_seed = |stage{ lv_ts }|.
ENDIF.
ms_control-page_menu = build_menu( ).
ENDMETHOD.
METHOD find_changed_by.
DATA: ls_local LIKE LINE OF it_local,
ls_changed_by LIKE LINE OF rt_changed_by.
FIELD-SYMBOLS: <ls_changed_by> LIKE LINE OF rt_changed_by.
LOOP AT it_local INTO ls_local WHERE NOT item IS INITIAL.
ls_changed_by-item = ls_local-item.
INSERT ls_changed_by INTO TABLE rt_changed_by.
ENDLOOP.
LOOP AT rt_changed_by ASSIGNING <ls_changed_by>.
TRY.
<ls_changed_by>-name = to_lower( zcl_abapgit_objects=>changed_by( <ls_changed_by>-item ) ).
CATCH zcx_abapgit_exception.
ENDTRY.
ENDLOOP.
ENDMETHOD.
METHOD process_stage_list.
DATA: lv_string TYPE string,
lt_fields TYPE tihttpnvp,
ls_file TYPE zif_abapgit_definitions=>ty_file.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF ms_files-local,
<ls_item> LIKE LINE OF lt_fields.
CONCATENATE LINES OF it_postdata INTO lv_string.
lt_fields = zcl_abapgit_html_action_utils=>parse_fields( lv_string ).
IF lines( lt_fields ) = 0.
zcx_abapgit_exception=>raise( 'process_stage_list: empty list' ).
ENDIF.
LOOP AT lt_fields ASSIGNING <ls_item>.
zcl_abapgit_path=>split_file_location(
EXPORTING
iv_fullpath = <ls_item>-name
IMPORTING
ev_path = ls_file-path
ev_filename = ls_file-filename ).
CASE <ls_item>-value.
WHEN zcl_abapgit_stage=>c_method-add.
READ TABLE ms_files-local ASSIGNING <ls_file>
WITH KEY file-path = ls_file-path
file-filename = ls_file-filename.
ASSERT sy-subrc = 0.
io_stage->add( iv_path = <ls_file>-file-path
iv_filename = <ls_file>-file-filename
iv_data = <ls_file>-file-data ).
WHEN zcl_abapgit_stage=>c_method-ignore.
io_stage->ignore( iv_path = ls_file-path
iv_filename = ls_file-filename ).
WHEN zcl_abapgit_stage=>c_method-rm.
io_stage->rm( iv_path = ls_file-path
iv_filename = ls_file-filename ).
WHEN zcl_abapgit_stage=>c_method-skip.
" Do nothing
WHEN OTHERS.
zcx_abapgit_exception=>raise( |process_stage_list: unknown method { <ls_item>-value }| ).
ENDCASE.
ENDLOOP.
ENDMETHOD. "process_stage_list
METHOD render_actions.
DATA: lv_local_count TYPE i,
lv_add_all_txt TYPE string.
CREATE OBJECT ro_html.
lv_local_count = lines( ms_files-local ).
IF lv_local_count > 0.
lv_add_all_txt = |Add all and commit ({ lv_local_count })|.
" Otherwise empty, but the element (id) is preserved for JS
ENDIF.
ro_html->add( '<table class="w100 margin-v5"><tr>' ).
" Action buttons
ro_html->add( '<td class="indent5em">' ).
ro_html->add_a( iv_act = 'errorStub(event)' " Will be reinit by JS
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_id = 'commitButton'
iv_style = 'display: none'
iv_txt = 'Commit (<span id="fileCounter"></span>)'
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ) ##NO_TEXT.
ro_html->add_a( iv_act = |{ c_action-stage_all }|
iv_id = 'commitAllButton'
iv_txt = lv_add_all_txt ) ##NO_TEXT.
ro_html->add( '</td>' ).
" Filter bar
ro_html->add( '<td class="right">' ).
ro_html->add( '<input class="stage-filter" id="objectSearch"' &&
' type="search" placeholder="Filter objects">' ).
ro_html->add( '</td>' ).
ro_html->add( '</tr></table>' ).
ENDMETHOD. "render_actions
METHOD render_content.
CREATE OBJECT ro_html.
ro_html->add( '<div class="repo">' ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top( mo_repo ) ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_js_error_banner( ) ).
ro_html->add( '<div class="stage-container">' ).
ro_html->add( render_actions( ) ).
ro_html->add( render_list( ) ).
ro_html->add( '</div>' ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_file.
DATA: lv_param TYPE string,
lv_filename TYPE string.
CREATE OBJECT ro_html.
lv_filename = is_file-path && is_file-filename.
REPLACE ALL OCCURRENCES OF ` ` IN lv_filename WITH ' '.
ro_html->add( |<tr class="{ iv_context }">| ).
CASE iv_context.
WHEN 'local'.
lv_param = zcl_abapgit_html_action_utils=>file_encode(
iv_key = mo_repo->get_key( )
ig_file = is_file ).
lv_filename = zcl_abapgit_html=>a(
iv_txt = lv_filename
iv_act = |{ zif_abapgit_definitions=>c_action-go_diff }?{ lv_param }| ).
ro_html->add( |<td class="type">{ is_item-obj_type }</td>| ).
ro_html->add( |<td class="name">{ lv_filename }</td>| ).
ro_html->add( |<td class="user">{ iv_changed_by }</td>| ).
WHEN 'remote'.
ro_html->add( '<td class="type">-</td>' ). " Dummy for object type
ro_html->add( |<td class="name">{ lv_filename }</td>| ).
ro_html->add( '<td></td>' ). " Dummy for changed-by
ENDCASE.
ro_html->add( |<td class="status">?</td>| ).
ro_html->add( '<td class="cmd"></td>' ). " Command added in JS
ro_html->add( '</tr>' ).
ENDMETHOD. "render_file
METHOD render_list.
DATA: lt_changed_by TYPE ty_changed_by_tt,
ls_changed_by LIKE LINE OF lt_changed_by.
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF ms_files-remote,
<ls_local> LIKE LINE OF ms_files-local.
CREATE OBJECT ro_html.
ro_html->add( '<table id="stageTab" class="stage_tab w100">' ).
lt_changed_by = find_changed_by( ms_files-local ).
" Local changes
LOOP AT ms_files-local ASSIGNING <ls_local>.
AT FIRST.
ro_html->add( '<thead><tr class="local">' ).
ro_html->add( '<th>Type</th>' ).
ro_html->add( '<th>Files to add (click to see diff)</th>' ).
ro_html->add( '<th>Changed by</th>' ).
ro_html->add( '<th></th>' ). " Status
ro_html->add( '<th class="cmd">' ).
ro_html->add( '<a>add</a>↓ <a>reset</a>↓' ).
ro_html->add( '</th>' ).
ro_html->add( '</tr></thead>' ).
ro_html->add( '<tbody>' ).
ENDAT.
READ TABLE lt_changed_by INTO ls_changed_by WITH KEY item = <ls_local>-item. "#EC CI_SUBRC
ro_html->add( render_file(
iv_context = 'local'
is_file = <ls_local>-file
is_item = <ls_local>-item
iv_changed_by = ls_changed_by-name ) ).
AT LAST.
ro_html->add('</tbody>').
ENDAT.
ENDLOOP.
" Remote changes
LOOP AT ms_files-remote ASSIGNING <ls_remote>.
AT FIRST.
ro_html->add( '<thead><tr class="remote">' ).
ro_html->add( '<th></th>' ). " Type
ro_html->add( '<th colspan="2">Files to remove or non-code</th>' ).
ro_html->add( '<th></th>' ). " Status
ro_html->add( '<th class="cmd">' ).
ro_html->add( '<a>ignore</a>↓ <a>remove</a>↓ <a>reset</a>↓' ).
ro_html->add( '</th>' ).
ro_html->add( '</tr></thead>' ).
ro_html->add( '<tbody>' ).
ENDAT.
ro_html->add( render_file(
iv_context = 'remote'
is_file = <ls_remote> ) ).
AT LAST.
ro_html->add('</tbody>').
ENDAT.
ENDLOOP.
ro_html->add( '</table>' ).
ENDMETHOD. "render_lines
METHOD scripts.
ro_html = super->scripts( ).
ro_html->add( 'var gStageParams = {' ).
ro_html->add( | seed: "{ mv_seed }",| ). " Unique page id
ro_html->add( ' formAction: "stage_commit",' ).
ro_html->add( ' ids: {' ).
ro_html->add( ' stageTab: "stageTab",' ).
ro_html->add( ' commitBtn: "commitButton",' ).
ro_html->add( ' commitAllBtn: "commitAllButton",' ).
ro_html->add( ' objectSearch: "objectSearch",' ).
ro_html->add( ' fileCounter: "fileCounter"' ).
ro_html->add( ' }' ).
ro_html->add( '}' ).
ro_html->add( 'var gHelper = new StageHelper(gStageParams);' ).
ENDMETHOD. "scripts
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA lo_stage TYPE REF TO zcl_abapgit_stage.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF ms_files-local.
CREATE OBJECT lo_stage.
CLEAR: ei_page, ev_state.
CASE iv_action.
WHEN c_action-stage_all.
LOOP AT ms_files-local ASSIGNING <ls_file>.
lo_stage->add( iv_path = <ls_file>-file-path
iv_filename = <ls_file>-file-filename
iv_data = <ls_file>-file-data ).
ENDLOOP.
WHEN c_action-stage_commit.
process_stage_list( it_postdata = it_postdata io_stage = lo_stage ).
WHEN OTHERS.
RETURN.
ENDCASE.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_commit
EXPORTING
io_repo = mo_repo
io_stage = lo_stage.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page_settings IMPLEMENTATION.
METHOD build_settings.
DATA: lv_i_param_value TYPE i,
lv_column TYPE string,
lt_key_bindings TYPE zif_abapgit_definitions=>tty_hotkey.
FIELD-SYMBOLS: <ls_post_field> TYPE ihttpnvp,
<ls_key_binding> TYPE zif_abapgit_definitions=>ty_hotkey.
CREATE OBJECT mo_settings.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'proxy_url'.
IF sy-subrc <> 0.
mv_error = abap_true.
ENDIF.
mo_settings->set_proxy_url( <ls_post_field>-value ).
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'proxy_port'.
IF sy-subrc <> 0.
mv_error = abap_true.
ENDIF.
mo_settings->set_proxy_port( <ls_post_field>-value ).
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'proxy_auth'.
IF sy-subrc = 0.
mo_settings->set_proxy_authentication( abap_true ).
ELSE.
mo_settings->set_proxy_authentication( abap_false ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'critical_tests'.
IF sy-subrc = 0.
mo_settings->set_run_critical_tests( abap_true ).
ELSE.
mo_settings->set_run_critical_tests( abap_false ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'experimental_features'.
IF sy-subrc = 0.
mo_settings->set_experimental_features( abap_true ).
ELSE.
mo_settings->set_experimental_features( abap_false ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'show_default_repo'.
IF sy-subrc = 0.
mo_settings->set_show_default_repo( abap_true ).
ELSE.
mo_settings->set_show_default_repo( abap_false ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'max_lines'.
IF sy-subrc = 0.
lv_i_param_value = <ls_post_field>-value.
mo_settings->set_max_lines( lv_i_param_value ).
ELSE.
mo_settings->set_max_lines( 0 ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'adt_jump_enabled'.
IF sy-subrc = 0.
mo_settings->set_adt_jump_enanbled( abap_true ).
ELSE.
mo_settings->set_adt_jump_enanbled( abap_false ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'link_hints_enabled'.
IF sy-subrc = 0.
mo_settings->set_link_hints_enabled( abap_true ).
ELSE.
mo_settings->set_link_hints_enabled( abap_false ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'link_hint_key'.
IF sy-subrc = 0.
mo_settings->set_link_hint_key( |{ <ls_post_field>-value }| ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'link_hint_background_color'.
IF sy-subrc = 0.
mo_settings->set_link_hint_background_color( |{ <ls_post_field>-value }| ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'comment_length'.
IF sy-subrc = 0.
lv_i_param_value = <ls_post_field>-value.
IF lv_i_param_value < zcl_abapgit_settings=>c_commitmsg_comment_length_dft.
lv_i_param_value = zcl_abapgit_settings=>c_commitmsg_comment_length_dft.
ENDIF.
mo_settings->set_commitmsg_comment_length( lv_i_param_value ).
ELSE.
mo_settings->set_commitmsg_comment_length( zcl_abapgit_settings=>c_commitmsg_comment_length_dft ).
ENDIF.
READ TABLE it_post_fields ASSIGNING <ls_post_field> WITH KEY name = 'body_size'.
IF sy-subrc = 0.
lv_i_param_value = <ls_post_field>-value.
IF lv_i_param_value < zcl_abapgit_settings=>c_commitmsg_body_size_dft.
lv_i_param_value = zcl_abapgit_settings=>c_commitmsg_body_size_dft.
ENDIF.
mo_settings->set_commitmsg_body_size( lv_i_param_value ).
ELSE.
mo_settings->set_commitmsg_body_size( zcl_abapgit_settings=>c_commitmsg_body_size_dft ).
ENDIF.
LOOP AT it_post_fields ASSIGNING <ls_post_field> WHERE name CP 'key*'.
FIND FIRST OCCURRENCE OF REGEX `key_(.*)_`
IN <ls_post_field>-name
SUBMATCHES lv_column.
CASE lv_column.
WHEN 'sequence'.
INSERT INITIAL LINE INTO TABLE lt_key_bindings ASSIGNING <ls_key_binding>.
<ls_key_binding>-sequence = <ls_post_field>-value.
WHEN 'action'.
<ls_key_binding>-action = <ls_post_field>-value.
ENDCASE.
ENDLOOP.
DELETE lt_key_bindings WHERE sequence IS INITIAL
OR action IS INITIAL.
mo_settings->set_hotkeys( lt_key_bindings ).
ENDMETHOD.
METHOD constructor.
super->constructor( ).
ms_control-page_title = 'SETTINGS'.
ENDMETHOD. " constructor.
METHOD get_default_hotkeys.
DATA: lt_actions TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action,
ls_hotkey LIKE LINE OF rt_default_hotkeys.
FIELD-SYMBOLS: <ls_action> LIKE LINE OF lt_actions.
lt_actions = zcl_abapgit_hotkeys=>get_default_hotkeys_from_pages( ).
LOOP AT lt_actions ASSIGNING <ls_action>.
ls_hotkey-action = <ls_action>-action.
ls_hotkey-sequence = <ls_action>-default_hotkey.
INSERT ls_hotkey INTO TABLE rt_default_hotkeys.
ENDLOOP.
ENDMETHOD.
METHOD get_possible_hotkey_actions.
DATA: ls_hotkey_action LIKE LINE OF rt_hotkey_actions.
rt_hotkey_actions = zcl_abapgit_hotkeys=>get_default_hotkeys_from_pages( ).
" insert empty row at the beginning, so that we can unset a hotkey
INSERT ls_hotkey_action INTO rt_hotkey_actions INDEX 1.
ENDMETHOD.
METHOD parse_post.
DATA lv_serialized_post_data TYPE string.
CONCATENATE LINES OF it_postdata INTO lv_serialized_post_data.
rt_post_fields = zcl_abapgit_html_action_utils=>parse_fields( lv_serialized_post_data ).
ENDMETHOD.
METHOD persist_settings.
DATA lo_settings_persistence TYPE REF TO zcl_abapgit_persist_settings.
lo_settings_persistence = zcl_abapgit_persist_settings=>get_instance( ).
lo_settings_persistence->modify( mo_settings ).
MESSAGE 'Settings succesfully saved' TYPE 'S'.
ENDMETHOD.
METHOD read_settings.
DATA lo_settings_persistence TYPE REF TO zcl_abapgit_persist_settings.
lo_settings_persistence = zcl_abapgit_persist_settings=>get_instance( ).
mo_settings = lo_settings_persistence->read( ).
ENDMETHOD.
METHOD render_adt_jump_enabled.
DATA lv_checked TYPE string.
IF mo_settings->get_adt_jump_enabled( ) = abap_true.
lv_checked = 'checked'.
ENDIF.
CREATE OBJECT ro_html.
ro_html->add( |<h2>ABAP Development Tools (ADT)</h2>| ).
ro_html->add( `<input type="checkbox" name="adt_jump_enabled" value="X" `
&& lv_checked && ` > Enable jump to ADT first` ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ENDMETHOD.
METHOD render_commit_msg.
CREATE OBJECT ro_html.
ro_html->add( |<h2>Commit Message</h2>| ).
ro_html->add( |<label for="comment_length">Max. length of comment (recommendation 50)</label>| ).
ro_html->add( |<br>| ).
ro_html->add( |<input name="comment_length" type="number" step="10" size="3" maxlength="3" min="50"| &&
| value="{ mo_settings->get_commitmsg_comment_length( ) }">| ).
ro_html->add( |<br>| ).
ro_html->add( |<label for="body_size">Max. line size of body (recommendation 72)</label>| ).
ro_html->add( |<br>| ).
ro_html->add( |<input name="body_size" type="number" size="3" maxlength="3" min="50"| &&
| value="{ mo_settings->get_commitmsg_body_size( ) }">| ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ENDMETHOD.
METHOD render_content.
CREATE OBJECT ro_html.
read_settings( ).
ro_html->add( render_form_begin( ) ).
ro_html->add( render_section_begin( |Global settings| ) ).
ro_html->add( render_proxy( ) ).
ro_html->add( |<hr>| ).
ro_html->add( render_commit_msg( ) ).
ro_html->add( |<hr>| ).
ro_html->add( render_development_internals( ) ).
ro_html->add( render_section_end( ) ).
ro_html->add( render_section_begin( |User specific settings| ) ).
ro_html->add( render_start_up( ) ).
ro_html->add( render_max_lines( ) ).
ro_html->add( |<hr>| ).
ro_html->add( render_adt_jump_enabled( ) ).
ro_html->add( |<hr>| ).
ro_html->add( render_link_hints( ) ).
ro_html->add( |<hr>| ).
ro_html->add( render_hotkeys( ) ).
ro_html->add( render_section_end( ) ).
ro_html->add( render_form_end( ) ).
ENDMETHOD. "render_content
METHOD render_development_internals.
DATA: lv_critical_tests TYPE string,
lv_experimental TYPE string.
IF mo_settings->get_run_critical_tests( ) = abap_true.
lv_critical_tests = 'checked'.
ENDIF.
IF mo_settings->get_experimental_features( ) = abap_true.
lv_experimental = 'checked'.
ENDIF.
CREATE OBJECT ro_html.
ro_html->add( |<h2>abapGit Development Internals settings</h2>| ).
ro_html->add( `<input type="checkbox" name="critical_tests" `
&& lv_critical_tests && ` > Enable critical unit tests (see LTCL_DANGEROUS)` ).
ro_html->add( |<br>| ).
ro_html->add( `<input type="checkbox" name="experimental_features" `
&& lv_experimental && ` > Enable experimental features` ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ENDMETHOD.
METHOD render_form_begin.
CREATE OBJECT ro_html.
ro_html->add( '<div class="settings_container">' ).
ro_html->add( `<form id="settings_form" method="post" action="sapevent:` && c_action-save_settings && `">` ).
ENDMETHOD.
METHOD render_form_end.
CREATE OBJECT ro_html.
ro_html->add( '<input type="submit" value="Save" class="submit">' ).
ro_html->add( '</form>' ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_hotkeys.
DATA: lv_index TYPE i,
lt_hotkeys TYPE zif_abapgit_definitions=>tty_hotkey,
lv_selected TYPE string,
lt_actions TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action.
FIELD-SYMBOLS: <ls_key_binding> LIKE LINE OF lt_hotkeys,
<ls_action> LIKE LINE OF lt_actions.
lt_hotkeys = mo_settings->get_hotkeys( ).
IF lines( lt_hotkeys ) = 0.
lt_hotkeys = get_default_hotkeys( ).
ENDIF.
DO 3 TIMES.
APPEND INITIAL LINE TO lt_hotkeys.
ENDDO.
CREATE OBJECT ro_html.
ro_html->add( |<h2>Hotkeys</h2>| ).
ro_html->add( |(Only available with installed abapGit repo)| ).
ro_html->add( |<br/>| ).
ro_html->add( |<br/>| ).
ro_html->add( '<table class="repo_tab" id="key_bindings" style="max-width: 300px;">' ).
ro_html->add( '<tr><th>key</th><th>action</th></tr>' ).
lt_actions = get_possible_hotkey_actions( ).
LOOP AT lt_hotkeys ASSIGNING <ls_key_binding>.
lv_index = sy-tabix.
ro_html->add( '<tr>' ).
ro_html->add( |<td><input name="key_sequence_{ lv_index }" maxlength=1 type="text" | &&
|value="{ <ls_key_binding>-sequence }"></td>| ).
ro_html->add( |<td><select name="key_action_{ lv_index }">| ).
LOOP AT lt_actions ASSIGNING <ls_action>.
IF <ls_key_binding>-action = <ls_action>-action.
lv_selected = 'selected'.
ELSE.
CLEAR: lv_selected.
ENDIF.
ro_html->add( |<option value="{ <ls_action>-action }" |
&& |{ lv_selected }>|
&& |{ <ls_action>-name }</option>| ).
ENDLOOP.
ro_html->add( '</select></td>' ).
ro_html->add( '</tr>' ).
ENDLOOP.
ro_html->add( '</select></td>' ).
ro_html->add( '</tr>' ).
ro_html->add( '</table>' ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ENDMETHOD.
METHOD render_link_hints.
DATA: lv_checked TYPE string,
lv_link_hint_key TYPE char01,
lv_link_background_color TYPE string.
IF mo_settings->get_link_hints_enabled( ) = abap_true.
lv_checked = 'checked'.
ENDIF.
lv_link_hint_key = mo_settings->get_link_hint_key( ).
lv_link_background_color = mo_settings->get_link_hint_background_color( ).
CREATE OBJECT ro_html.
ro_html->add( |<h2>Vimium like link hints</h2>| ).
ro_html->add( `<input type="checkbox" name="link_hints_enabled" value="X" `
&& lv_checked && ` > Enable Vimium like link hints` ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ro_html->add( |<input type="text" name="link_hint_key" size="1" maxlength="1" value="{ lv_link_hint_key }" |
&& |> Single key to activate links| ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ro_html->add( |<input type="text" name="link_hint_background_color" size="20" maxlength="20"|
&& | value="{ lv_link_background_color }"|
&& |> Background Color (HTML colors e.g. lightgreen or #42f47a)| ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ENDMETHOD.
METHOD render_max_lines.
CREATE OBJECT ro_html.
ro_html->add( |<h2>List size</h2>| ).
ro_html->add( |<label for="max_lines">Max. # of objects listed (0 = all)</label>| ).
ro_html->add( |<br>| ).
ro_html->add( `<input name="max_lines" type="text" size="5" value="` && mo_settings->get_max_lines( ) && `">` ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ENDMETHOD.
METHOD render_proxy.
CREATE OBJECT ro_html.
ro_html->add( |<h2>Proxy</h2>| ).
ro_html->add( |<label for="proxy_url">Proxy URL</label>| ).
ro_html->add( |<br>| ).
ro_html->add( `<input name="proxy_url" type="text" size="50" value="` &&
mo_settings->get_proxy_url( ) && `">` ).
ro_html->add( |<br>| ).
ro_html->add( |<label for="proxy_port">Proxy Port</label>| ).
ro_html->add( |<br>| ).
ro_html->add( `<input name="proxy_port" type="text" size="5" value="` &&
mo_settings->get_proxy_port( ) && `">` ).
ro_html->add( |<br>| ).
ro_html->add( |<label for="proxy_auth">Proxy Authentication</label>| ).
IF mo_settings->get_proxy_authentication( ) = abap_true.
ro_html->add( `<input name="proxy_auth" type="checkbox" checked>` ).
ELSE.
ro_html->add( `<input name="proxy_auth" type="checkbox">` ).
ENDIF.
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ENDMETHOD.
METHOD render_section_begin.
CREATE OBJECT ro_html.
ro_html->add( |<h1>{ iv_header }</h1>| ).
ro_html->add( |<div class="settings_section">| ).
ENDMETHOD.
METHOD render_section_end.
CREATE OBJECT ro_html.
ro_html->add( |</div>| ).
ENDMETHOD.
METHOD render_start_up.
DATA lv_checked TYPE string.
IF mo_settings->get_show_default_repo( ) = abap_true.
lv_checked = 'checked'.
ENDIF.
CREATE OBJECT ro_html.
ro_html->add( |<h2>Start up</h2>| ).
ro_html->add( `<input type="checkbox" name="show_default_repo" value="X" `
&& lv_checked && ` > Show last repo` ).
ro_html->add( |<br>| ).
ro_html->add( |<br>| ).
ENDMETHOD.
METHOD validate_settings.
IF ( mo_settings->get_proxy_url( ) IS NOT INITIAL AND mo_settings->get_proxy_port( ) IS INITIAL ) OR
( mo_settings->get_proxy_url( ) IS INITIAL AND mo_settings->get_proxy_port( ) IS NOT INITIAL ).
MESSAGE 'If specifying proxy, specify both URL and port' TYPE 'W'.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA:
lt_post_fields TYPE tihttpnvp.
CASE iv_action.
WHEN c_action-save_settings.
lt_post_fields = parse_post( it_postdata ).
build_settings( lt_post_fields ).
validate_settings( ).
IF mv_error = abap_true.
MESSAGE 'Error when saving settings. Open an issue at https://github.com/larshp/abapGit' TYPE 'E'.
ELSE.
persist_settings( ).
ENDIF.
ev_state = zif_abapgit_definitions=>c_event_state-go_back.
ENDCASE.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_REPO_SETT IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
ms_control-page_title = 'REPO SETTINGS'.
mo_repo = io_repo.
ENDMETHOD. " constructor.
METHOD parse_post.
DATA lv_serialized_post_data TYPE string.
CONCATENATE LINES OF it_postdata INTO lv_serialized_post_data.
rt_post_fields = zcl_abapgit_html_action_utils=>parse_fields( lv_serialized_post_data ).
ENDMETHOD.
METHOD render_content.
CREATE OBJECT ro_html.
ro_html->add( '<div class="settings_container">' ).
ro_html->add( '<form id="settings_form" method="post" action="sapevent:' &&
c_action-save_settings && '">' ).
render_dot_abapgit( ro_html ).
render_local_settings( ro_html ).
ro_html->add( '<br><input type="submit" value="Save" class="submit">' ).
ro_html->add( '</form>' ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_dot_abapgit.
CONSTANTS: lc_requirement_edit_count TYPE i VALUE 5.
DATA: ls_dot TYPE zif_abapgit_dot_abapgit=>ty_dot_abapgit,
lv_selected TYPE string,
lt_folder_logic TYPE stringtab,
lv_req_index TYPE i,
lv_requirement_count TYPE i.
FIELD-SYMBOLS: <lv_folder_logic> TYPE LINE OF stringtab,
<ls_requirement> TYPE zif_abapgit_dot_abapgit=>ty_requirement.
ls_dot = mo_repo->get_dot_abapgit( )->get_data( ).
lv_requirement_count = lines( ls_dot-requirements ).
IF lv_requirement_count < lc_requirement_edit_count.
DO - lv_requirement_count + lc_requirement_edit_count TIMES.
INSERT INITIAL LINE INTO TABLE ls_dot-requirements.
ENDDO.
ENDIF.
INSERT zif_abapgit_dot_abapgit=>c_folder_logic-full
INTO TABLE lt_folder_logic.
INSERT zif_abapgit_dot_abapgit=>c_folder_logic-prefix
INTO TABLE lt_folder_logic.
io_html->add( '<h2>.abapgit.xml</h2>' ).
io_html->add( 'Folder logic: <select name="folder_logic">' ).
LOOP AT lt_folder_logic ASSIGNING <lv_folder_logic>.
IF ls_dot-folder_logic = <lv_folder_logic>.
lv_selected = 'selected'.
ELSE.
CLEAR: lv_selected.
ENDIF.
io_html->add( |<option value="{ <lv_folder_logic> }" |
&& |{ lv_selected }>|
&& |{ <lv_folder_logic> }</option>| ).
ENDLOOP.
io_html->add( '</select>' ).
io_html->add( '<br>' ).
io_html->add( 'Starting folder: <input name="starting_folder" type="text" size="10" value="' &&
ls_dot-starting_folder && '">' ).
io_html->add( '<br>' ).
io_html->add( '<h3>Requirements</h3>' ).
io_html->add( '<table class="repo_tab" id="requirement-tab" style="max-width: 300px;">' ).
io_html->add( '<tr><th>Software Component</th><th>Min Release</th><th>Min Patch</th></tr>' ).
LOOP AT ls_dot-requirements ASSIGNING <ls_requirement>.
lv_req_index = sy-tabix.
io_html->add( '<tr>' ).
io_html->add( |<td><input name="req_com_{ lv_req_index }" maxlength=30 type="text" | &&
|value="{ <ls_requirement>-component }"></td>| ).
io_html->add( |<td><input name="req_rel_{ lv_req_index }" maxlength=10 type="text" | &&
|value="{ <ls_requirement>-min_release }"></td>| ).
io_html->add( |<td><input name="req_pat_{ lv_req_index }" maxlength=10 type="text" | &&
|value="{ <ls_requirement>-min_patch }"></td>| ).
io_html->add( '</tr>' ).
ENDLOOP.
io_html->add( '</table>' ).
ENDMETHOD.
METHOD render_local_settings.
DATA: lv_checked TYPE string,
ls_settings TYPE zif_abapgit_persistence=>ty_repo-local_settings.
ls_settings = mo_repo->get_local_settings( ).
io_html->add( '<h2>Local settings</h2>' ).
CLEAR lv_checked.
IF ls_settings-write_protected = abap_true.
lv_checked = | checked|.
ENDIF.
io_html->add( |Write protected <input name="write_protected" type="checkbox"{ lv_checked }><br>| ).
CLEAR lv_checked.
IF ls_settings-ignore_subpackages = abap_true.
lv_checked = | checked|.
ENDIF.
io_html->add( |Ignore subpackages <input name="ignore_subpackages" type="checkbox"{ lv_checked }><br>| ).
CLEAR lv_checked.
IF ls_settings-only_local_objects = abap_true.
lv_checked = | checked|.
ENDIF.
io_html->add( |Only local objects <input name="only_local_objects" type="checkbox"{ lv_checked }><br>| ).
io_html->add( '<br>' ).
io_html->add( 'Code inspector check variant: <input name="check_variant" type="text" size="30" value="' &&
ls_settings-code_inspector_check_variant && '">' ).
io_html->add( '<br>' ).
CLEAR lv_checked.
IF ls_settings-block_commit = abap_true.
lv_checked = | checked|.
ENDIF.
io_html->add( |Block commit commit/push if code inspection has erros: |
&& |<input name="block_commit" type="checkbox"{ lv_checked }><br>| ).
ENDMETHOD.
METHOD save.
DATA: lt_post_fields TYPE tihttpnvp.
lt_post_fields = parse_post( it_postdata ).
save_dot_abap( lt_post_fields ).
save_local_settings( lt_post_fields ).
mo_repo->refresh( ).
ENDMETHOD.
METHOD save_dot_abap.
DATA: lo_dot TYPE REF TO zcl_abapgit_dot_abapgit,
ls_post_field LIKE LINE OF it_post_fields,
lt_requirements TYPE zif_abapgit_dot_abapgit=>ty_requirement_tt.
FIELD-SYMBOLS: <ls_requirement> TYPE zif_abapgit_dot_abapgit=>ty_requirement.
lo_dot = mo_repo->get_dot_abapgit( ).
READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'folder_logic'.
ASSERT sy-subrc = 0.
lo_dot->set_folder_logic( ls_post_field-value ).
READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'starting_folder'.
ASSERT sy-subrc = 0.
lo_dot->set_starting_folder( ls_post_field-value ).
LOOP AT it_post_fields INTO ls_post_field WHERE name CP 'req_*'.
CASE ls_post_field-name+4(3).
WHEN 'com'.
INSERT INITIAL LINE INTO TABLE lt_requirements ASSIGNING <ls_requirement>.
<ls_requirement>-component = ls_post_field-value.
WHEN 'rel'.
<ls_requirement>-min_release = ls_post_field-value.
WHEN 'pat'.
<ls_requirement>-min_patch = ls_post_field-value.
ENDCASE.
ENDLOOP.
SORT lt_requirements BY component min_release min_patch.
DELETE lt_requirements WHERE component IS INITIAL.
DELETE ADJACENT DUPLICATES FROM lt_requirements COMPARING ALL FIELDS.
lo_dot->set_requirements( lt_requirements ).
mo_repo->set_dot_abapgit( lo_dot ).
ENDMETHOD.
METHOD save_local_settings.
DATA: ls_settings TYPE zif_abapgit_persistence=>ty_repo-local_settings,
ls_post_field LIKE LINE OF it_post_fields,
lv_check_variant TYPE sci_chkv.
ls_settings = mo_repo->get_local_settings( ).
READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'write_protected' value = 'on'.
IF sy-subrc = 0.
ls_settings-write_protected = abap_true.
ELSE.
ls_settings-write_protected = abap_false.
ENDIF.
READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'ignore_subpackages' value = 'on'.
IF sy-subrc = 0.
ls_settings-ignore_subpackages = abap_true.
ELSE.
ls_settings-ignore_subpackages = abap_false.
ENDIF.
READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'only_local_objects' value = 'on'.
IF sy-subrc = 0.
ls_settings-only_local_objects = abap_true.
ELSE.
ls_settings-only_local_objects = abap_false.
ENDIF.
READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'check_variant'.
ASSERT sy-subrc = 0.
lv_check_variant = to_upper( ls_post_field-value ).
IF ls_post_field-value IS NOT INITIAL.
zcl_abapgit_code_inspector=>validate_check_variant( lv_check_variant ).
ENDIF.
ls_settings-code_inspector_check_variant = lv_check_variant.
READ TABLE it_post_fields INTO ls_post_field WITH KEY name = 'block_commit' value = 'on'.
IF sy-subrc = 0.
ls_settings-block_commit = abap_true.
ELSE.
ls_settings-block_commit = abap_false.
ENDIF.
IF ls_settings-block_commit = abap_true
AND ls_settings-code_inspector_check_variant IS INITIAL.
zcx_abapgit_exception=>raise( |If block commit is active, a check variant has to be maintained.| ).
ENDIF.
mo_repo->set_local_settings( ls_settings ).
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
CASE iv_action.
WHEN c_action-save_settings.
save( it_postdata ).
ev_state = zif_abapgit_definitions=>c_event_state-go_back.
ENDCASE.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_REPO_OVER IMPLEMENTATION.
METHOD add_direction_option.
DATA: lv_selected TYPE string.
IF iv_selected = abap_true.
lv_selected = 'selected'.
ENDIF.
io_html->add( |<option value="{ iv_option }" { lv_selected }>|
&& |{ to_mixed( iv_option ) }</option>| ).
ENDMETHOD.
METHOD add_order_by_option.
DATA: lv_selected TYPE string.
IF mv_order_by = iv_option.
lv_selected = 'selected'.
ENDIF.
io_html->add( |<option value="{ iv_option }" { lv_selected }>|
&& |{ to_mixed( iv_option ) }</option>| ).
ENDMETHOD.
METHOD apply_filter.
IF mv_filter IS NOT INITIAL.
DELETE ct_overview WHERE key NS mv_filter
AND name NS mv_filter
AND url NS mv_filter
AND package NS mv_filter
AND branch NS mv_filter
AND created_by NS mv_filter
AND created_at NS mv_filter
AND deserialized_by NS mv_filter
AND deserialized_at NS mv_filter.
ENDIF.
ENDMETHOD.
METHOD apply_order_by.
DATA:
lt_sort TYPE abap_sortorder_tab,
ls_sort LIKE LINE OF lt_sort.
IF mv_order_by IS NOT INITIAL.
ls_sort-name = mv_order_by.
ls_sort-descending = mv_order_descending.
ls_sort-astext = abap_true.
INSERT ls_sort INTO TABLE lt_sort.
SORT ct_overview BY (lt_sort).
ENDIF.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
ms_control-page_title = |Repository Overview|.
mv_order_by = |NAME|.
CALL FUNCTION 'GET_SYSTEM_TIMEZONE'
IMPORTING
timezone = mv_time_zone
EXCEPTIONS
customizing_missing = 1
OTHERS = 2.
ASSERT sy-subrc = 0.
ENDMETHOD. " constructor.
METHOD map_repo_list_to_overview.
DATA: ls_overview LIKE LINE OF rt_overview,
lo_repo_srv TYPE REF TO zcl_abapgit_repo,
lv_date TYPE d,
lv_time TYPE t.
FIELD-SYMBOLS: <ls_repo> LIKE LINE OF it_repo_list.
LOOP AT it_repo_list ASSIGNING <ls_repo>.
CLEAR: ls_overview.
lo_repo_srv = zcl_abapgit_repo_srv=>get_instance( )->get( <ls_repo>-key ).
ls_overview-favorite = zcl_abapgit_persistence_user=>get_instance(
)->is_favorite_repo( <ls_repo>-key ).
ls_overview-type = <ls_repo>-offline.
ls_overview-key = <ls_repo>-key.
ls_overview-name = lo_repo_srv->get_name( ).
ls_overview-url = <ls_repo>-url.
ls_overview-package = <ls_repo>-package.
ls_overview-branch = zcl_abapgit_git_branch_list=>get_display_name( <ls_repo>-branch_name ).
ls_overview-created_by = <ls_repo>-created_by.
IF <ls_repo>-created_at IS NOT INITIAL.
CONVERT TIME STAMP <ls_repo>-created_at
TIME ZONE mv_time_zone
INTO DATE lv_date
TIME lv_time.
ls_overview-created_at = |{ lv_date DATE = USER } { lv_time TIME = USER }|.
ENDIF.
ls_overview-deserialized_by = <ls_repo>-deserialized_by.
IF <ls_repo>-deserialized_at IS NOT INITIAL.
CONVERT TIME STAMP <ls_repo>-deserialized_at
TIME ZONE mv_time_zone
INTO DATE lv_date
TIME lv_time.
ls_overview-deserialized_at = |{ lv_date DATE = USER } { lv_time TIME = USER }|.
ENDIF.
INSERT ls_overview INTO TABLE rt_overview.
ENDLOOP.
ENDMETHOD.
METHOD parse_change_order_by.
FIELD-SYMBOLS: <lv_postdata> TYPE cnht_post_data_line.
READ TABLE it_postdata ASSIGNING <lv_postdata>
INDEX 1.
IF sy-subrc = 0.
FIND FIRST OCCURRENCE OF REGEX `orderBy=(.*)`
IN <lv_postdata>
SUBMATCHES mv_order_by.
ENDIF.
mv_order_by = condense( mv_order_by ).
ENDMETHOD.
METHOD parse_direction.
DATA: lv_direction TYPE string.
FIELD-SYMBOLS: <lv_postdata> TYPE cnht_post_data_line.
CLEAR: mv_order_descending.
READ TABLE it_postdata ASSIGNING <lv_postdata>
INDEX 1.
IF sy-subrc = 0.
FIND FIRST OCCURRENCE OF REGEX `direction=(.*)`
IN <lv_postdata>
SUBMATCHES lv_direction.
ENDIF.
IF condense( lv_direction ) = 'DESCENDING'.
mv_order_descending = abap_true.
ENDIF.
ENDMETHOD.
METHOD parse_filter.
FIELD-SYMBOLS: <lv_postdata> LIKE LINE OF it_postdata.
READ TABLE it_postdata ASSIGNING <lv_postdata>
INDEX 1.
IF sy-subrc = 0.
FIND FIRST OCCURRENCE OF REGEX `filter=(.*)`
IN <lv_postdata>
SUBMATCHES mv_filter.
ENDIF.
mv_filter = condense( mv_filter ).
ENDMETHOD.
METHOD render_content.
DATA: lt_overview TYPE tty_overview.
lt_overview = map_repo_list_to_overview(
zcl_abapgit_persist_factory=>get_repo( )->list( ) ).
apply_order_by( CHANGING ct_overview = lt_overview ).
apply_filter( CHANGING ct_overview = lt_overview ).
CREATE OBJECT ro_html.
ro_html->add( |<div class="form-container">| ).
ro_html->add( |<form id="commit_form" class="grey70"|
&& | method="post" action="sapevent:{ c_action-apply_filter }">| ).
render_header_bar( ro_html ).
render_table( io_html = ro_html
it_overview = lt_overview ).
ro_html->add( |</div>| ).
ENDMETHOD. "render_content
METHOD render_header_bar.
io_html->add( |<div class="row">| ).
render_order_by( io_html ).
render_order_by_direction( io_html ).
io_html->add( render_text_input( iv_name = |filter|
iv_label = |Filter: |
iv_value = mv_filter ) ).
io_html->add( |<input type="submit" class="hidden-submit">| ).
io_html->add( |</div>| ).
io_html->add( |</form>| ).
io_html->add( |</div>| ).
ENDMETHOD.
METHOD render_order_by.
io_html->add( |Order by: <select name="order_by" onchange="onOrderByChange(this)">| ).
add_order_by_option( iv_option = |TYPE|
io_html = io_html ).
add_order_by_option( iv_option = |KEY|
io_html = io_html ).
add_order_by_option( iv_option = |NAME|
io_html = io_html ).
add_order_by_option( iv_option = |URL|
io_html = io_html ).
add_order_by_option( iv_option = |PACKAGE|
io_html = io_html ).
add_order_by_option( iv_option = |BRANCH|
io_html = io_html ).
add_order_by_option( iv_option = |CREATED_BY|
io_html = io_html ).
add_order_by_option( iv_option = |CREATED_AT|
io_html = io_html ).
add_order_by_option( iv_option = |DESERIALIZED_BY|
io_html = io_html ).
add_order_by_option( iv_option = |DESERIALIZED_AT|
io_html = io_html ).
io_html->add( |</select>| ).
ENDMETHOD.
METHOD render_order_by_direction.
io_html->add( |<select name="direction" onchange="onDirectionChange(this)">| ).
add_direction_option( iv_option = |ASCENDING|
iv_selected = mv_order_descending
io_html = io_html ).
add_direction_option( iv_option = |DESCENDING|
iv_selected = mv_order_descending
io_html = io_html ).
io_html->add( |</select>| ).
ENDMETHOD.
METHOD render_table.
io_html->add( |<div class="db_list">| ).
io_html->add( |<table class="db_tab">| ).
render_table_header( io_html ).
render_table_body( io_html = io_html
it_overview = it_overview ).
io_html->add( |</tbody>| ).
io_html->add( |</table>| ).
ENDMETHOD.
METHOD render_table_body.
DATA: lv_trclass TYPE string,
lv_type_icon TYPE string,
lv_favorite_icon TYPE string.
FIELD-SYMBOLS: <ls_overview> LIKE LINE OF it_overview.
LOOP AT it_overview ASSIGNING <ls_overview>.
CLEAR lv_trclass.
IF sy-tabix = 1.
lv_trclass = ' class="firstrow"' ##NO_TEXT.
ENDIF.
IF <ls_overview>-type = abap_true.
lv_type_icon = 'plug/darkgrey'.
ELSE.
lv_type_icon = 'cloud-upload/blue'.
ENDIF.
IF <ls_overview>-favorite = abap_true.
lv_favorite_icon = 'star/blue'.
ELSE.
lv_favorite_icon = 'star/grey'.
ENDIF.
io_html->add( |<tr{ lv_trclass }>| ).
io_html->add( |<td>| ).
io_html->add_a( iv_act = |{ zif_abapgit_definitions=>c_action-repo_toggle_fav }?{ <ls_overview>-key }|
iv_txt = zcl_abapgit_html=>icon( iv_name = lv_favorite_icon
iv_class = 'pad-sides'
iv_hint = 'Click to toggle favorite' ) ).
io_html->add( |</td>| ).
io_html->add( |<td>{ zcl_abapgit_html=>icon( lv_type_icon ) }</td>| ).
io_html->add( |<td>{ <ls_overview>-key }</td>| ).
io_html->add( |<td>{ zcl_abapgit_html=>a( iv_txt = <ls_overview>-name
iv_act = |{ c_action-select }?{ <ls_overview>-key }| ) }</td>| ).
io_html->add( |<td>{ <ls_overview>-url }</td>| ).
io_html->add( |<td>{ <ls_overview>-package }</td>| ).
io_html->add( |<td>{ <ls_overview>-branch }</td>| ).
io_html->add( |<td>{ <ls_overview>-created_by }</td>| ).
io_html->add( |<td>{ <ls_overview>-created_at }</td>| ).
io_html->add( |<td>{ <ls_overview>-deserialized_by }</td>| ).
io_html->add( |<td>{ <ls_overview>-deserialized_at }</td>| ).
io_html->add( |<td>| ).
io_html->add( |</td>| ).
io_html->add( |</tr>| ).
ENDLOOP.
ENDMETHOD.
METHOD render_table_header.
io_html->add( |<thead>| ).
io_html->add( |<tr>| ).
io_html->add( |<th>Favorite</th>| ).
io_html->add( |<th>Type</th>| ).
io_html->add( |<th>Key</th>| ).
io_html->add( |<th>Name</th>| ).
io_html->add( |<th>Url</th>| ).
io_html->add( |<th>Package</th>| ).
io_html->add( |<th>Branch name</th>| ).
io_html->add( |<th>Creator</th>| ).
io_html->add( |<th>Created at [{ mv_time_zone }]</th>| ).
io_html->add( |<th>Deserialized by</th>| ).
io_html->add( |<th>Deserialized at [{ mv_time_zone }]</th>| ).
io_html->add( |<th></th>| ).
io_html->add( '</tr>' ).
io_html->add( '</thead>' ).
io_html->add( '<tbody>' ).
ENDMETHOD.
METHOD render_text_input.
DATA lv_attrs TYPE string.
CREATE OBJECT ro_html.
IF iv_value IS NOT INITIAL.
lv_attrs = | value="{ iv_value }"|.
ENDIF.
IF iv_max_length IS NOT INITIAL.
lv_attrs = | maxlength="{ iv_max_length }"|.
ENDIF.
ro_html->add( |<label for="{ iv_name }">{ iv_label }</label>| ).
ro_html->add( |<input id="{ iv_name }" name="{ iv_name }" type="text"{ lv_attrs }>| ).
ENDMETHOD. " render_text_input
METHOD scripts.
ro_html = super->scripts( ).
ro_html->add( 'setInitialFocus("filter");' ).
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA: lv_key TYPE zif_abapgit_persistence=>ty_value.
CASE iv_action.
WHEN c_action-select.
lv_key = iv_getdata.
zcl_abapgit_persistence_user=>get_instance( )->set_repo_show( lv_key ).
TRY.
zcl_abapgit_repo_srv=>get_instance( )->get( lv_key )->refresh( ).
CATCH zcx_abapgit_exception ##NO_HANDLER.
ENDTRY.
ev_state = zif_abapgit_definitions=>c_event_state-go_back.
WHEN c_action-change_order_by.
parse_change_order_by( it_postdata ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_action-direction.
parse_direction( it_postdata ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_action-apply_filter.
parse_filter( it_postdata ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page_merge_res IMPLEMENTATION.
METHOD apply_merged_content.
CONSTANTS: lc_replace TYPE string VALUE '<<new>>'.
DATA: BEGIN OF ls_filedata,
merge_content TYPE string,
END OF ls_filedata.
DATA: lv_string TYPE string,
lt_fields TYPE tihttpnvp,
lv_new_file_content TYPE xstring.
FIELD-SYMBOLS: <lv_postdata_line> LIKE LINE OF it_postdata,
<ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict.
LOOP AT it_postdata ASSIGNING <lv_postdata_line>.
lv_string = |{ lv_string }{ <lv_postdata_line> }|.
ENDLOOP.
REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_crlf IN lv_string WITH lc_replace.
REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_newline IN lv_string WITH lc_replace.
lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( lv_string ).
zcl_abapgit_html_action_utils=>get_field( EXPORTING iv_name = 'MERGE_CONTENT'
it_field = lt_fields
CHANGING cg_field = ls_filedata ).
ls_filedata-merge_content = cl_http_utility=>unescape_url( escaped = ls_filedata-merge_content ).
REPLACE ALL OCCURRENCES OF lc_replace IN ls_filedata-merge_content WITH zif_abapgit_definitions=>c_newline.
lv_new_file_content = zcl_abapgit_convert=>string_to_xstring_utf8( iv_string = ls_filedata-merge_content ).
READ TABLE mt_conflicts ASSIGNING <ls_conflict> INDEX mv_current_conflict_index.
<ls_conflict>-result_sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>c_type-blob
iv_data = lv_new_file_content ).
<ls_conflict>-result_data = lv_new_file_content.
mo_merge->resolve_conflict( is_conflict = <ls_conflict> ).
ENDMETHOD.
METHOD build_menu.
CREATE OBJECT ro_menu.
ro_menu->add( iv_txt = 'Toggle merge mode' iv_act = c_actions-toggle_mode ) ##NO_TEXT.
ro_menu->add( iv_txt = 'Cancel' iv_act = c_actions-cancel ) ##NO_TEXT.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
mo_repo = io_repo.
ms_control-page_title = 'Resolve Conflicts'.
ms_control-page_menu = build_menu( ).
mo_merge_page = io_merge_page.
mo_merge = io_merge.
mv_merge_mode = c_merge_mode-selection.
mv_current_conflict_index = 1.
mt_conflicts = io_merge->get_conflicts( ).
ENDMETHOD.
METHOD is_binary.
DATA: lv_len TYPE i,
lv_idx TYPE i,
lv_x TYPE x.
FIELD-SYMBOLS <lv_data> LIKE iv_d1.
IF iv_d1 IS NOT INITIAL. " One of them might be new and so empty
ASSIGN iv_d1 TO <lv_data>.
ELSE.
ASSIGN iv_d2 TO <lv_data>.
ENDIF.
lv_len = xstrlen( <lv_data> ).
IF lv_len = 0.
RETURN.
ENDIF.
IF lv_len > 100.
lv_len = 100.
ENDIF.
" Simple char range test
" stackoverflow.com/questions/277521/how-to-identify-the-file-content-as-ascii-or-binary
DO lv_len TIMES. " I'm sure there is more efficient way ...
lv_idx = sy-index - 1.
lv_x = <lv_data>+lv_idx(1).
IF NOT ( lv_x BETWEEN 9 AND 13 OR lv_x BETWEEN 32 AND 126 ).
rv_yes = abap_true.
EXIT.
ENDIF.
ENDDO.
ENDMETHOD. " is_binary.
METHOD render_beacon.
DATA: lv_beacon TYPE string.
CREATE OBJECT ro_html.
IF is_diff_line-beacon > 0.
READ TABLE is_diff-o_diff->mt_beacons INTO lv_beacon INDEX is_diff_line-beacon.
ELSE.
lv_beacon = '---'.
ENDIF.
ro_html->add( '<thead class="nav_line">' ).
ro_html->add( '<tr>' ).
ro_html->add( '<th class="num"></th>' ).
ro_html->add( |<th colspan="3">@@ { is_diff_line-new_num } @@ { lv_beacon }</th>| ).
ro_html->add( '</tr>' ).
ro_html->add( '</thead>' ).
ENDMETHOD. " render_beacon.
METHOD render_content.
resolve_diff( ).
IF ms_diff_file IS INITIAL.
zcx_abapgit_exception=>raise( 'no conflict found' ).
ENDIF.
CREATE OBJECT ro_html.
ro_html->add( |<div id="diff-list" data-repo-key="{ mo_repo->get_key( ) }">| ).
ro_html->add( render_diff( ms_diff_file ) ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD render_diff.
DATA: lv_target_content TYPE string.
FIELD-SYMBOLS: <ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict.
CREATE OBJECT ro_html.
ro_html->add( |<div class="diff" data-type="{ is_diff-type
}" data-changed-by="{ is_diff-changed_by
}" data-file="{ is_diff-path && is_diff-filename }">| ). "#EC NOTEXT
ro_html->add( render_diff_head( is_diff ) ).
" Content
IF is_diff-type <> 'binary'.
IF mv_merge_mode EQ c_merge_mode-selection.
ro_html->add( '<div class="diff_content">' ). "#EC NOTEXT
ro_html->add( '<table class="diff_tab syntax-hl">' ). "#EC NOTEXT
ro_html->add( render_table_head( ) ).
ro_html->add( render_lines( is_diff ) ).
ro_html->add( '</table>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ELSE.
"Table for Div-Table and textarea
ro_html->add( '<div class="diff_content">' ). "#EC NOTEXT
ro_html->add( '<table>' ). "#EC NOTEXT
ro_html->add( '<thead class="header">' ). "#EC NOTEXT
ro_html->add( '<tr>' ). "#EC NOTEXT
ro_html->add( '<th>Code</th>' ). "#EC NOTEXT
ro_html->add( '<th>Merge - ' ). "#EC NOTEXT
ro_html->add_a( iv_act = 'submitFormById(''merge_form'');' "#EC NOTEXT
iv_txt = 'Apply'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ).
ro_html->add( '</th> ' ). "#EC NOTEXT
ro_html->add( '</tr>' ). "#EC NOTEXT
ro_html->add( '</thead>' ). "#EC NOTEXT
ro_html->add( '<td>' ).
"Diff-Table of source and target file
ro_html->add( '<table class="diff_tab syntax-hl">' ). "#EC NOTEXT
ro_html->add( render_table_head( ) ).
ro_html->add( render_lines( is_diff ) ).
ro_html->add( '</table>' ). "#EC NOTEXT
READ TABLE mt_conflicts ASSIGNING <ls_conflict> INDEX mv_current_conflict_index.
IF sy-subrc EQ 0.
lv_target_content = zcl_abapgit_convert=>xstring_to_string_utf8( <ls_conflict>-target_data ).
lv_target_content = escape( val = lv_target_content format = cl_abap_format=>e_html_text ).
ENDIF.
ro_html->add( '</td>' ). "#EC NOTEXT
ro_html->add( '<td>' ). "#EC NOTEXT
ro_html->add( '<div class="form-container">' ).
ro_html->add( |<form id="merge_form" class="aligned-form" accept-charset="UTF-8"| ).
ro_html->add( |method="post" action="sapevent:apply_merge">| ).
ro_html->add( |<textarea id="merge_content" name="merge_content" | ).
ro_html->add( |rows="{ lines( is_diff-o_diff->get( ) ) }">{ lv_target_content }</textarea>| ).
ro_html->add( '<input type="submit" class="hidden-submit">' ).
ro_html->add( '</form>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ro_html->add( '</td>' ). "#EC NOTEXT
ro_html->add( '</table>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ENDIF.
ELSE.
ro_html->add( '<div class="diff_content paddings center grey">' ). "#EC NOTEXT
ro_html->add( 'The content seems to be binary.' ). "#EC NOTEXT
ro_html->add( 'Cannot display as diff.' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ENDIF.
ro_html->add( '</div>' ). "#EC NOTEXT
ENDMETHOD. " render_diff
METHOD render_diff_head.
DATA: ls_stats TYPE zif_abapgit_definitions=>ty_count.
CREATE OBJECT ro_html.
ro_html->add( '<div class="diff_head">' ). "#EC NOTEXT
IF is_diff-type <> 'binary' AND is_diff-o_diff IS NOT INITIAL.
ls_stats = is_diff-o_diff->stats( ).
ro_html->add( |<span class="diff_banner diff_ins">+ { ls_stats-insert }</span>| ).
ro_html->add( |<span class="diff_banner diff_del">- { ls_stats-delete }</span>| ).
ro_html->add( |<span class="diff_banner diff_upd">~ { ls_stats-update }</span>| ).
ENDIF.
ro_html->add( |<span class="diff_name">{ is_diff-filename }</span>| ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ENDMETHOD.
METHOD render_lines.
DATA: lo_highlighter TYPE REF TO zcl_abapgit_syntax_highlighter,
lt_diffs TYPE zif_abapgit_definitions=>ty_diffs_tt,
lv_insert_nav TYPE abap_bool.
FIELD-SYMBOLS <ls_diff> LIKE LINE OF lt_diffs.
lo_highlighter = zcl_abapgit_syntax_highlighter=>create( is_diff-filename ).
CREATE OBJECT ro_html.
lt_diffs = is_diff-o_diff->get( ).
LOOP AT lt_diffs ASSIGNING <ls_diff>.
IF <ls_diff>-short = abap_false.
lv_insert_nav = abap_true.
CONTINUE.
ENDIF.
IF lv_insert_nav = abap_true. " Insert separator line with navigation
ro_html->add( render_beacon( is_diff_line = <ls_diff> is_diff = is_diff ) ).
lv_insert_nav = abap_false.
ENDIF.
IF lo_highlighter IS BOUND.
<ls_diff>-new = lo_highlighter->process_line( <ls_diff>-new ).
<ls_diff>-old = lo_highlighter->process_line( <ls_diff>-old ).
ELSE.
<ls_diff>-new = escape( val = <ls_diff>-new format = cl_abap_format=>e_html_attr ).
<ls_diff>-old = escape( val = <ls_diff>-old format = cl_abap_format=>e_html_attr ).
ENDIF.
CONDENSE <ls_diff>-new_num. "get rid of leading spaces
CONDENSE <ls_diff>-old_num.
ro_html->add( render_line_split( is_diff_line = <ls_diff>
iv_fstate = is_diff-fstate ) ).
ENDLOOP.
ENDMETHOD. "render_lines
METHOD render_line_split.
DATA: lv_new TYPE string,
lv_old TYPE string,
lv_mark TYPE string,
lv_bg TYPE string.
CREATE OBJECT ro_html.
" New line
lv_mark = ` `.
IF is_diff_line-result = zif_abapgit_definitions=>c_diff-update.
lv_bg = ' diff_upd'.
lv_mark = `~`.
ELSEIF is_diff_line-result = zif_abapgit_definitions=>c_diff-insert.
lv_bg = ' diff_ins'.
lv_mark = `+`.
ENDIF.
lv_new = |<td class="num" line-num="{ is_diff_line-new_num }"></td>|
&& |<td class="code{ lv_bg }">{ lv_mark }{ is_diff_line-new }</td>|.
" Old line
CLEAR lv_bg.
lv_mark = ` `.
IF is_diff_line-result = zif_abapgit_definitions=>c_diff-update.
lv_bg = ' diff_upd'.
lv_mark = `~`.
ELSEIF is_diff_line-result = zif_abapgit_definitions=>c_diff-delete.
lv_bg = ' diff_del'.
lv_mark = `-`.
ENDIF.
lv_old = |<td class="num" line-num="{ is_diff_line-old_num }"></td>|
&& |<td class="code{ lv_bg }">{ lv_mark }{ is_diff_line-old }</td>|.
" render line, inverse sides if remote is newer
ro_html->add( '<tr>' ). "#EC NOTEXT
ro_html->add( lv_old ). " Target
ro_html->add( lv_new ). " Source
ro_html->add( '</tr>' ). "#EC NOTEXT
ENDMETHOD. "render_line_split
METHOD render_table_head.
CREATE OBJECT ro_html.
IF mv_merge_mode EQ c_merge_mode-selection.
ro_html->add( '<thead class="header">' ). "#EC NOTEXT
ro_html->add( '<tr>' ). "#EC NOTEXT
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
ro_html->add( '<form id="target_form" method="post" action="sapevent:apply_target">' ). "#EC NOTEXT
ro_html->add( '<th>Target - ' && mo_repo->get_branch_name( ) && ' - ' ). "#EC NOTEXT
ro_html->add_a( iv_act = 'submitFormById(''target_form'');' "#EC NOTEXT
iv_txt = 'Apply'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ).
ro_html->add( '</th> ' ). "#EC NOTEXT
ro_html->add( '</form>' ). "#EC NOTEXT
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
ro_html->add( '<form id="source_form" method="post" action="sapevent:apply_source">' ). "#EC NOTEXT
ro_html->add( '<th>Source - ' && mo_merge->get_source_branch( ) &&' - ' ). "#EC NOTEXT
ro_html->add_a( iv_act = 'submitFormById(''source_form'');' "#EC NOTEXT
iv_txt = 'Apply'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ).
ro_html->add( '</th> ' ). "#EC NOTEXT
ro_html->add( '</form>' ). "#EC NOTEXT
ro_html->add( '</tr>' ). "#EC NOTEXT
ro_html->add( '</thead>' ). "#EC NOTEXT
ELSE.
ro_html->add( '<thead class="header">' ). "#EC NOTEXT
ro_html->add( '<tr>' ). "#EC NOTEXT
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
ro_html->add( '<th>Target - ' && mo_repo->get_branch_name( ) &&'</th> ' ). "#EC NOTEXT
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
ro_html->add( '<th>Source - ' && mo_merge->get_source_branch( ) &&'</th> ' ). "#EC NOTEXT
ro_html->add( '</tr>' ). "#EC NOTEXT
ro_html->add( '</thead>' ). "#EC NOTEXT
ENDIF.
ENDMETHOD. " render_table_head.
METHOD resolve_diff.
DATA: lv_offs TYPE i.
FIELD-SYMBOLS: <ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict.
CLEAR ms_diff_file.
READ TABLE mt_conflicts ASSIGNING <ls_conflict> INDEX mv_current_conflict_index.
IF sy-subrc NE 0.
RETURN.
ENDIF.
ms_diff_file-path = <ls_conflict>-path.
ms_diff_file-filename = <ls_conflict>-filename.
ms_diff_file-type = reverse( <ls_conflict>-filename ).
FIND FIRST OCCURRENCE OF '.' IN ms_diff_file-type MATCH OFFSET lv_offs.
ms_diff_file-type = reverse( substring( val = ms_diff_file-type len = lv_offs ) ).
IF ms_diff_file-type <> 'xml' AND ms_diff_file-type <> 'abap'.
ms_diff_file-type = 'other'.
ENDIF.
IF ms_diff_file-type = 'other'
AND is_binary( iv_d1 = <ls_conflict>-source_data iv_d2 = <ls_conflict>-target_data ) = abap_true.
ms_diff_file-type = 'binary'.
ENDIF.
IF ms_diff_file-type <> 'binary'.
CREATE OBJECT ms_diff_file-o_diff
EXPORTING
iv_new = <ls_conflict>-source_data
iv_old = <ls_conflict>-target_data.
ENDIF.
ENDMETHOD.
METHOD toggle_merge_mode.
IF mv_merge_mode EQ c_merge_mode-selection.
mv_merge_mode = c_merge_mode-merge.
ELSE.
mv_merge_mode = c_merge_mode-selection.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
FIELD-SYMBOLS: <ls_conflict> TYPE zif_abapgit_definitions=>ty_merge_conflict.
CASE iv_action.
WHEN c_actions-apply_merge
OR c_actions-apply_source
OR c_actions-apply_target
OR c_actions-cancel.
CASE iv_action.
WHEN c_actions-apply_merge.
apply_merged_content( it_postdata = it_postdata ).
WHEN c_actions-apply_source.
READ TABLE mt_conflicts ASSIGNING <ls_conflict> INDEX mv_current_conflict_index.
<ls_conflict>-result_sha1 = <ls_conflict>-source_sha1.
<ls_conflict>-result_data = <ls_conflict>-source_data.
mo_merge->resolve_conflict( is_conflict = <ls_conflict> ).
WHEN c_actions-apply_target.
READ TABLE mt_conflicts ASSIGNING <ls_conflict> INDEX mv_current_conflict_index.
<ls_conflict>-result_sha1 = <ls_conflict>-target_sha1.
<ls_conflict>-result_data = <ls_conflict>-target_data.
mo_merge->resolve_conflict( is_conflict = <ls_conflict> ).
ENDCASE.
mv_current_conflict_index = mv_current_conflict_index + 1.
IF mv_current_conflict_index > lines( mt_conflicts ).
CLEAR mv_current_conflict_index.
ENDIF.
IF mv_current_conflict_index IS NOT INITIAL.
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
ELSE.
ei_page = mo_merge_page.
ev_state = zif_abapgit_definitions=>c_event_state-go_back.
ENDIF.
WHEN c_actions-toggle_mode.
toggle_merge_mode( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page_merge IMPLEMENTATION.
METHOD build_menu.
CREATE OBJECT ro_menu.
ro_menu->add( iv_txt = 'Merge' iv_act = c_actions-merge iv_cur = abap_false ) ##NO_TEXT.
IF iv_with_conflict EQ abap_true.
ro_menu->add( iv_txt = 'Resolve Conflicts' iv_act = c_actions-res_conflicts ) ##NO_TEXT.
ENDIF.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
mo_repo = io_repo.
io_repo->set_branch_name( |refs/heads/{ iv_target }| ).
CREATE OBJECT mo_merge
EXPORTING
io_repo = io_repo
iv_source_branch = iv_source.
mo_merge->run( ).
ms_control-page_title = 'MERGE'.
ms_control-page_menu = build_menu( iv_with_conflict = mo_merge->has_conflicts( ) ).
ENDMETHOD.
METHOD render_content.
DEFINE _show_file.
READ TABLE &1 ASSIGNING <ls_show>
WITH KEY path = <ls_file>-path name = <ls_file>-name.
IF sy-subrc = 0.
IF <ls_show>-sha1 = ls_result-sha1.
ro_html->add( |<td>{
<ls_show>-path }{ <ls_show>-name }</td><td><b>{
<ls_show>-sha1(7) }</b></td>| ).
ELSE.
ro_html->add( |<td>{
<ls_show>-path }{ <ls_show>-name }</td><td>{
<ls_show>-sha1(7) }</td>| ).
ENDIF.
ELSE.
ro_html->add( '<td></td><td></td>' ).
ENDIF.
END-OF-DEFINITION.
DATA: ls_merge TYPE zif_abapgit_definitions=>ty_merge,
lt_files LIKE ls_merge-stree,
ls_result LIKE LINE OF ls_merge-result.
FIELD-SYMBOLS: <ls_show> LIKE LINE OF lt_files,
<ls_file> LIKE LINE OF lt_files.
ls_merge = mo_merge->get_result( ).
"If now exists no conflicts anymore, conflicts button should disappear
ms_control-page_menu = build_menu( iv_with_conflict = mo_merge->has_conflicts( ) ).
CREATE OBJECT ro_html.
ro_html->add( '<div id="toc">' ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top(
io_repo = mo_repo
iv_show_package = abap_false
iv_show_branch = abap_false ) ).
ro_html->add( '<table>' ).
ro_html->add( '<tr>' ).
ro_html->add( '<td>Source</td>' ).
ro_html->add( '<td>' ).
ro_html->add( ls_merge-source-name ).
ro_html->add( '</td></tr>' ).
ro_html->add( '<tr>' ).
ro_html->add( '<td>Target</td>' ).
ro_html->add( '<td>' ).
ro_html->add( ls_merge-target-name ).
ro_html->add( '</td></tr>' ).
ro_html->add( '<tr>' ).
ro_html->add( '<td>Ancestor</td>' ).
ro_html->add( '<td>' ).
ro_html->add( ls_merge-common-commit ).
ro_html->add( '</td></tr>' ).
ro_html->add( '</table>' ).
ro_html->add( '<br>' ).
APPEND LINES OF ls_merge-stree TO lt_files.
APPEND LINES OF ls_merge-ttree TO lt_files.
APPEND LINES OF ls_merge-ctree TO lt_files.
SORT lt_files BY path DESCENDING name ASCENDING.
DELETE ADJACENT DUPLICATES FROM lt_files COMPARING path name.
ro_html->add( '<table>' ).
ro_html->add( '<tr>' ).
ro_html->add( '<td><u>Source</u></td>' ).
ro_html->add( '<td></td>' ).
ro_html->add( '<td><u>Target</u></td>' ).
ro_html->add( '<td></td>' ).
ro_html->add( '<td><u>Ancestor</u></td>' ).
ro_html->add( '<td></td>' ).
ro_html->add( '<td><u>Result</u></td>' ).
ro_html->add( '<td></td>' ).
ro_html->add( '</tr>' ).
LOOP AT lt_files ASSIGNING <ls_file>.
CLEAR ls_result.
READ TABLE ls_merge-result INTO ls_result
WITH KEY path = <ls_file>-path name = <ls_file>-name.
ro_html->add( '<tr>' ).
_show_file ls_merge-stree.
_show_file ls_merge-ttree.
_show_file ls_merge-ctree.
_show_file ls_merge-result.
ro_html->add( '</tr>' ).
ENDLOOP.
ro_html->add( '</table>' ).
ro_html->add( '<br>' ).
ro_html->add( '<b>' ).
ro_html->add( ls_merge-conflict ).
ro_html->add( '</b>' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD zif_abapgit_gui_page~on_event.
CASE iv_action.
WHEN c_actions-merge.
IF mo_merge->has_conflicts( ) EQ abap_true.
zcx_abapgit_exception=>raise( 'conflicts exists' ).
ENDIF.
IF mo_merge->get_result( )-stage->count( ) EQ 0.
zcx_abapgit_exception=>raise( 'nothing to merge' ).
ENDIF.
IF mo_repo->get_local_settings( )-code_inspector_check_variant IS NOT INITIAL.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_code_insp
EXPORTING
io_repo = mo_repo
io_stage = mo_merge->get_result( )-stage.
ELSE.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_commit
EXPORTING
io_repo = mo_repo
io_stage = mo_merge->get_result( )-stage.
ENDIF.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
WHEN c_actions-res_conflicts.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_merge_res
EXPORTING
io_repo = mo_repo
io_merge_page = me
io_merge = mo_merge.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page_main IMPLEMENTATION.
METHOD build_main_menu.
DATA: lo_advsub TYPE REF TO zcl_abapgit_html_toolbar,
lo_helpsub TYPE REF TO zcl_abapgit_html_toolbar.
CREATE OBJECT ro_menu.
CREATE OBJECT lo_advsub.
CREATE OBJECT lo_helpsub.
lo_advsub->add( iv_txt = 'Repository overview'
iv_act = zif_abapgit_definitions=>c_action-go_repo_overview ) ##NO_TEXT.
lo_advsub->add( iv_txt = 'Database util'
iv_act = zif_abapgit_definitions=>c_action-go_db ) ##NO_TEXT.
lo_advsub->add( iv_txt = 'Package to zip'
iv_act = zif_abapgit_definitions=>c_action-zip_package ) ##NO_TEXT.
lo_advsub->add( iv_txt = 'Transport to zip'
iv_act = zif_abapgit_definitions=>c_action-zip_transport ) ##NO_TEXT.
lo_advsub->add( iv_txt = 'Object to files'
iv_act = zif_abapgit_definitions=>c_action-zip_object ) ##NO_TEXT.
lo_advsub->add( iv_txt = 'Test changed by'
iv_act = c_actions-changed_by ) ##NO_TEXT.
lo_advsub->add( iv_txt = 'Page playground'
iv_act = zif_abapgit_definitions=>c_action-go_playground ) ##NO_TEXT.
lo_advsub->add( iv_txt = 'Debug info'
iv_act = zif_abapgit_definitions=>c_action-go_debuginfo ) ##NO_TEXT.
lo_advsub->add( iv_txt = 'Settings'
iv_act = zif_abapgit_definitions=>c_action-go_settings ) ##NO_TEXT.
lo_helpsub->add( iv_txt = 'Tutorial'
iv_act = zif_abapgit_definitions=>c_action-go_tutorial ) ##NO_TEXT.
lo_helpsub->add( iv_txt = 'Documentation'
iv_act = c_actions-documentation ) ##NO_TEXT.
ro_menu->add( iv_txt = '+ Online'
iv_act = zif_abapgit_definitions=>c_action-repo_newonline ) ##NO_TEXT.
ro_menu->add( iv_txt = '+ Offline'
iv_act = zif_abapgit_definitions=>c_action-repo_newoffline ) ##NO_TEXT.
ro_menu->add( iv_txt = 'Explore'
iv_act = zif_abapgit_definitions=>c_action-go_explore ) ##NO_TEXT.
ro_menu->add( iv_txt = 'Advanced'
io_sub = lo_advsub ) ##NO_TEXT.
ro_menu->add( iv_txt = 'Help'
io_sub = lo_helpsub ) ##NO_TEXT.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
ms_control-page_title = 'HOME'.
ms_control-page_menu = build_main_menu( ).
ENDMETHOD.
METHOD render_content.
DATA: lt_repos TYPE zif_abapgit_definitions=>ty_repo_ref_tt,
lx_error TYPE REF TO zcx_abapgit_exception,
lo_tutorial TYPE REF TO zcl_abapgit_gui_view_tutorial,
lo_repo LIKE LINE OF lt_repos.
retrieve_active_repo( ). " Get and validate key of user default repo
CREATE OBJECT ro_html.
TRY.
lt_repos = zcl_abapgit_repo_srv=>get_instance( )->list( ).
CATCH zcx_abapgit_exception INTO lx_error.
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_error( ix_error = lx_error ) ).
RETURN.
ENDTRY.
ro_html->add( render_toc( lt_repos ) ).
IF mv_show IS INITIAL OR lines( lt_repos ) = 0.
CREATE OBJECT lo_tutorial.
ro_html->add( lo_tutorial->render( ) ).
ELSE.
lo_repo = zcl_abapgit_repo_srv=>get_instance( )->get( mv_show ).
ro_html->add( render_repo( lo_repo ) ).
ENDIF.
ENDMETHOD.
METHOD render_repo.
DATA lo_news TYPE REF TO zcl_abapgit_news.
CREATE OBJECT ro_html.
lo_news = zcl_abapgit_news=>create( io_repo ).
ro_html->add( |<div class="repo" id="repo{ io_repo->get_key( ) }">| ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top(
io_repo = io_repo
io_news = lo_news
iv_interactive_branch = abap_true ) ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_news( io_news = lo_news ) ).
ro_html->add( mo_repo_content->render( ) ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_toc.
DATA: lo_pback TYPE REF TO zcl_abapgit_persist_background,
lv_current TYPE abap_bool,
lv_key TYPE zif_abapgit_persistence=>ty_repo-key,
lv_icon TYPE string,
lo_repo LIKE LINE OF it_repo_list,
lo_favbar TYPE REF TO zcl_abapgit_html_toolbar,
lo_allbar TYPE REF TO zcl_abapgit_html_toolbar,
lt_favorites TYPE zcl_abapgit_persistence_user=>tt_favorites,
lv_repo_title TYPE string.
CREATE OBJECT ro_html.
CREATE OBJECT lo_favbar.
CREATE OBJECT lo_allbar.
CREATE OBJECT lo_pback.
lt_favorites = zcl_abapgit_persistence_user=>get_instance( )->get_favorites( ).
LOOP AT it_repo_list INTO lo_repo.
lv_key = lo_repo->get_key( ).
lv_current = abap_false.
IF lv_key = mv_show.
lv_current = abap_true.
ENDIF.
lv_repo_title = lo_repo->get_name( ).
IF lo_pback->exists( lv_key ) = abap_true.
lv_repo_title = lv_repo_title && '<sup>bg</sup>'. " Background marker
ENDIF.
READ TABLE lt_favorites TRANSPORTING NO FIELDS
WITH KEY table_line = lv_key.
IF sy-subrc = 0.
DELETE lt_favorites INDEX sy-tabix. " for later cleanup
lo_favbar->add( iv_txt = lv_repo_title
iv_act = |{ c_actions-show }?{ lv_key }|
iv_cur = lv_current ).
ENDIF.
IF lo_repo->is_offline( ) = abap_true.
lv_icon = 'plug/darkgrey'.
ELSE.
lv_icon = 'cloud-upload/blue'.
ENDIF.
lo_allbar->add( iv_txt = lv_repo_title
iv_act = |{ c_actions-show }?{ lv_key }|
iv_ico = lv_icon
iv_cur = lv_current ).
ENDLOOP.
" Cleanup orphan favorites (for removed repos)
LOOP AT lt_favorites INTO lv_key.
zcl_abapgit_persistence_user=>get_instance( )->toggle_favorite( lv_key ).
ENDLOOP.
" Render HTML
ro_html->add( '<div id="toc">' ) ##NO_TEXT. " TODO refactor html & css
ro_html->add( '<div class="toc_grid">' ) ##NO_TEXT.
ro_html->add( '<div class="toc_row">' ) ##NO_TEXT.
ro_html->add( '<table class="w100"><tr>' ).
ro_html->add( |<td class="pad-sides">{
zcl_abapgit_html=>icon( iv_name = 'star/blue' iv_hint = 'Favorites' )
}</td>| ).
ro_html->add( '<td class="pad-sides w100 favorites">' ). " Maximize width
IF lo_favbar->count( ) > 0.
ro_html->add( lo_favbar->render( iv_sort = abap_true ) ).
ELSE.
ro_html->add( |<span class="grey">No favorites so far. For more info please check {
zcl_abapgit_html=>a( iv_txt = 'tutorial' iv_act = zif_abapgit_definitions=>c_action-go_tutorial )
}</span>| ).
ENDIF.
ro_html->add( '</td>' ).
ro_html->add( '<td>' ).
ro_html->add( lo_allbar->render_as_droplist(
iv_label = zcl_abapgit_html=>icon( iv_name = 'three-bars/blue' )
iv_action = c_actions-overview
iv_right = abap_true
iv_sort = abap_true ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr></table>' ).
ro_html->add( '</div>' ).
ro_html->add( '</div>' ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD retrieve_active_repo.
DATA: lv_show_old LIKE mv_show.
TRY.
zcl_abapgit_repo_srv=>get_instance( )->list( ).
CATCH zcx_abapgit_exception.
RETURN.
ENDTRY.
lv_show_old = mv_show.
mv_show = zcl_abapgit_persistence_user=>get_instance( )->get_repo_show( ). " Get default repo from user cfg
IF mv_show IS NOT INITIAL.
TRY. " verify the key exists
zcl_abapgit_repo_srv=>get_instance( )->get( mv_show ).
CATCH zcx_abapgit_exception.
CLEAR mv_show.
zcl_abapgit_persistence_user=>get_instance( )->set_repo_show( mv_show ).
ENDTRY.
ENDIF.
IF lv_show_old <> mv_show AND NOT mv_show IS INITIAL.
CREATE OBJECT mo_repo_content
EXPORTING
iv_key = mv_show. " Reinit content state
ENDIF.
ENDMETHOD.
METHOD test_changed_by.
DATA: ls_tadir TYPE zif_abapgit_definitions=>ty_tadir,
lv_user TYPE xubname,
ls_item TYPE zif_abapgit_definitions=>ty_item.
ls_tadir = zcl_abapgit_ui_factory=>get_popups( )->popup_object( ).
IF ls_tadir IS INITIAL.
RETURN.
ENDIF.
ls_item-obj_type = ls_tadir-object.
ls_item-obj_name = ls_tadir-obj_name.
lv_user = zcl_abapgit_objects=>changed_by( ls_item ).
MESSAGE lv_user TYPE 'S'.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA: lv_key TYPE zif_abapgit_persistence=>ty_repo-key,
li_repo_overview TYPE REF TO zif_abapgit_gui_page.
IF NOT mo_repo_content IS INITIAL.
mo_repo_content->zif_abapgit_gui_page~on_event(
EXPORTING
iv_action = iv_action
iv_prev_page = iv_prev_page
iv_getdata = iv_getdata
it_postdata = it_postdata
IMPORTING
ei_page = ei_page
ev_state = ev_state ).
IF ev_state <> zif_abapgit_definitions=>c_event_state-not_handled.
RETURN.
ENDIF.
ENDIF.
lv_key = iv_getdata.
CASE iv_action.
WHEN c_actions-show.
zcl_abapgit_persistence_user=>get_instance( )->set_repo_show( lv_key ).
TRY.
zcl_abapgit_repo_srv=>get_instance( )->get( lv_key )->refresh( ).
CATCH zcx_abapgit_exception ##NO_HANDLER.
ENDTRY.
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_actions-changed_by.
test_changed_by( ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN c_actions-documentation.
zcl_abapgit_services_abapgit=>open_abapgit_wikipage( ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
WHEN c_actions-overview.
CREATE OBJECT li_repo_overview TYPE zcl_abapgit_gui_page_repo_over.
ei_page = li_repo_overview.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
DATA: ls_hotkey_action TYPE zif_abapgit_gui_page_hotkey=>ty_hotkey_action.
ls_hotkey_action-name = |Main: Settings|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-go_settings.
ls_hotkey_action-default_hotkey = |x|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Main: Stage|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-go_stage.
ls_hotkey_action-default_hotkey = |s|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Main: Switch branch|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-git_branch_switch.
ls_hotkey_action-default_hotkey = |b|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Main: Repo overview|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-go_repo_overview.
ls_hotkey_action-default_hotkey = |o|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Main: Refresh|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-repo_refresh.
ls_hotkey_action-default_hotkey = |r|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Main: Pull|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-git_pull.
ls_hotkey_action-default_hotkey = |p|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Main: + Online|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-repo_newonline.
ls_hotkey_action-default_hotkey = |n|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Main: Uninstall|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-repo_purge.
ls_hotkey_action-default_hotkey = |u|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Main: Show diff|.
ls_hotkey_action-action = zif_abapgit_definitions=>c_action-go_diff.
ls_hotkey_action-default_hotkey = |d|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_EXPLORE IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
ms_control-redirect_url = c_explore_url.
ENDMETHOD. "constructor
METHOD render_content.
ASSERT 1 = 1. " Dummy
ENDMETHOD. "render_content.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page_diff IMPLEMENTATION.
METHOD append_diff.
DATA:
lv_offs TYPE i,
ls_r_dummy LIKE LINE OF it_remote ##NEEDED,
ls_l_dummy LIKE LINE OF it_local ##NEEDED.
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF it_remote,
<ls_local> LIKE LINE OF it_local,
<ls_diff> LIKE LINE OF mt_diff_files.
READ TABLE it_remote ASSIGNING <ls_remote>
WITH KEY filename = is_status-filename
path = is_status-path.
IF sy-subrc <> 0.
ASSIGN ls_r_dummy TO <ls_remote>.
ENDIF.
READ TABLE it_local ASSIGNING <ls_local>
WITH KEY file-filename = is_status-filename
file-path = is_status-path.
IF sy-subrc <> 0.
ASSIGN ls_l_dummy TO <ls_local>.
ENDIF.
IF <ls_local> IS INITIAL AND <ls_remote> IS INITIAL.
zcx_abapgit_exception=>raise( |DIFF: file not found { is_status-filename }| ).
ENDIF.
APPEND INITIAL LINE TO mt_diff_files ASSIGNING <ls_diff>.
<ls_diff>-path = is_status-path.
<ls_diff>-filename = is_status-filename.
<ls_diff>-lstate = is_status-lstate.
<ls_diff>-rstate = is_status-rstate.
IF <ls_diff>-lstate IS NOT INITIAL AND <ls_diff>-rstate IS NOT INITIAL.
<ls_diff>-fstate = c_fstate-both.
ELSEIF <ls_diff>-lstate IS NOT INITIAL.
<ls_diff>-fstate = c_fstate-local.
ELSE. "rstate IS NOT INITIAL, lstate = empty.
<ls_diff>-fstate = c_fstate-remote.
ENDIF.
" Changed by
IF <ls_local>-item-obj_type IS NOT INITIAL.
<ls_diff>-changed_by = to_lower( zcl_abapgit_objects=>changed_by( <ls_local>-item ) ).
ENDIF.
" Extension
IF <ls_local>-file-filename IS NOT INITIAL.
<ls_diff>-type = reverse( <ls_local>-file-filename ).
ELSE.
<ls_diff>-type = reverse( <ls_remote>-filename ).
ENDIF.
FIND FIRST OCCURRENCE OF '.' IN <ls_diff>-type MATCH OFFSET lv_offs.
<ls_diff>-type = reverse( substring( val = <ls_diff>-type len = lv_offs ) ).
IF <ls_diff>-type <> 'xml' AND <ls_diff>-type <> 'abap'.
<ls_diff>-type = 'other'.
ENDIF.
IF <ls_diff>-type = 'other'
AND is_binary( iv_d1 = <ls_remote>-data iv_d2 = <ls_local>-file-data ) = abap_true.
<ls_diff>-type = 'binary'.
ENDIF.
" Diff data
IF <ls_diff>-type <> 'binary'.
IF <ls_diff>-fstate = c_fstate-remote. " Remote file leading changes
CREATE OBJECT <ls_diff>-o_diff
EXPORTING
iv_new = <ls_remote>-data
iv_old = <ls_local>-file-data.
ELSE. " Local leading changes or both were modified
CREATE OBJECT <ls_diff>-o_diff
EXPORTING
iv_new = <ls_local>-file-data
iv_old = <ls_remote>-data.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD build_menu.
DATA: lo_sub TYPE REF TO zcl_abapgit_html_toolbar,
lt_types TYPE string_table,
lt_users TYPE string_table.
FIELD-SYMBOLS: <ls_diff> LIKE LINE OF mt_diff_files,
<lv_i> TYPE string.
" Get unique
LOOP AT mt_diff_files ASSIGNING <ls_diff>.
APPEND <ls_diff>-type TO lt_types.
APPEND <ls_diff>-changed_by TO lt_users.
ENDLOOP.
SORT: lt_types, lt_users.
DELETE ADJACENT DUPLICATES FROM: lt_types, lt_users.
CREATE OBJECT ro_menu.
IF lines( lt_types ) > 1 OR lines( lt_users ) > 1.
CREATE OBJECT lo_sub EXPORTING iv_id = 'diff-filter'.
" File types
IF lines( lt_types ) > 1.
lo_sub->add( iv_txt = 'TYPE' iv_typ = zif_abapgit_definitions=>c_action_type-separator ).
LOOP AT lt_types ASSIGNING <lv_i>.
lo_sub->add( iv_txt = <lv_i>
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_aux = 'type'
iv_chk = abap_true ).
ENDLOOP.
ENDIF.
" Changed by
IF lines( lt_users ) > 1.
lo_sub->add( iv_txt = 'CHANGED BY' iv_typ = zif_abapgit_definitions=>c_action_type-separator ).
LOOP AT lt_users ASSIGNING <lv_i>.
lo_sub->add( iv_txt = <lv_i>
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_aux = 'changed-by'
iv_chk = abap_true ).
ENDLOOP.
ENDIF.
ro_menu->add( iv_txt = 'Filter'
io_sub = lo_sub ) ##NO_TEXT.
ENDIF.
ro_menu->add( iv_txt = 'Split/Unified view'
iv_act = c_actions-toggle_unified ) ##NO_TEXT.
ENDMETHOD.
METHOD constructor.
DATA: lt_remote TYPE zif_abapgit_definitions=>ty_files_tt,
lt_local TYPE zif_abapgit_definitions=>ty_files_item_tt,
lt_status TYPE zif_abapgit_definitions=>ty_results_tt,
lo_repo TYPE REF TO zcl_abapgit_repo_online,
lv_ts TYPE timestamp.
FIELD-SYMBOLS: <ls_status> LIKE LINE OF lt_status.
super->constructor( ).
ms_control-page_title = 'DIFF'.
mv_unified = zcl_abapgit_persistence_user=>get_instance( )->get_diff_unified( ).
mv_repo_key = iv_key.
GET TIME STAMP FIELD lv_ts.
mv_seed = |diff{ lv_ts }|. " Generate based on time
ASSERT is_file IS INITIAL OR is_object IS INITIAL. " just one passed
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( iv_key ).
lt_remote = lo_repo->get_files_remote( ).
lt_local = lo_repo->get_files_local( ).
lt_status = lo_repo->status( ).
IF is_file IS NOT INITIAL. " Diff for one file
READ TABLE lt_status ASSIGNING <ls_status>
WITH KEY path = is_file-path filename = is_file-filename.
append_diff( it_remote = lt_remote
it_local = lt_local
is_status = <ls_status> ).
ELSEIF is_object IS NOT INITIAL. " Diff for whole object
LOOP AT lt_status ASSIGNING <ls_status>
WHERE obj_type = is_object-obj_type
AND obj_name = is_object-obj_name
AND match IS INITIAL.
append_diff( it_remote = lt_remote
it_local = lt_local
is_status = <ls_status> ).
ENDLOOP.
ELSE. " Diff for the whole repo
LOOP AT lt_status ASSIGNING <ls_status> WHERE match IS INITIAL.
append_diff( it_remote = lt_remote
it_local = lt_local
is_status = <ls_status> ).
ENDLOOP.
ENDIF.
IF lines( mt_diff_files ) = 0.
zcx_abapgit_exception=>raise( 'PAGE_DIFF ERROR: No diff files found' ).
ENDIF.
ms_control-page_menu = build_menu( ).
ENDMETHOD.
METHOD is_binary.
DATA: lv_len TYPE i,
lv_idx TYPE i,
lv_x TYPE x.
FIELD-SYMBOLS <lv_data> LIKE iv_d1.
IF iv_d1 IS NOT INITIAL. " One of them might be new and so empty
ASSIGN iv_d1 TO <lv_data>.
ELSE.
ASSIGN iv_d2 TO <lv_data>.
ENDIF.
lv_len = xstrlen( <lv_data> ).
IF lv_len = 0.
RETURN.
ENDIF.
IF lv_len > 100.
lv_len = 100.
ENDIF.
" Simple char range test
" stackoverflow.com/questions/277521/how-to-identify-the-file-content-as-ascii-or-binary
DO lv_len TIMES. " I'm sure there is more efficient way ...
lv_idx = sy-index - 1.
lv_x = <lv_data>+lv_idx(1).
IF NOT ( lv_x BETWEEN 9 AND 13 OR lv_x BETWEEN 32 AND 126 ).
rv_yes = abap_true.
EXIT.
ENDIF.
ENDDO.
ENDMETHOD.
METHOD render_beacon.
DATA: lv_beacon TYPE string.
CREATE OBJECT ro_html.
IF is_diff_line-beacon > 0.
READ TABLE is_diff-o_diff->mt_beacons INTO lv_beacon INDEX is_diff_line-beacon.
ELSE.
lv_beacon = '---'.
ENDIF.
ro_html->add( '<thead class="nav_line">' ).
ro_html->add( '<tr>' ).
ro_html->add( '<th class="num"></th>' ).
IF mv_unified = abap_true.
ro_html->add( '<th class="num"></th>' ).
ro_html->add( |<th>@@ { is_diff_line-new_num } @@ { lv_beacon }</th>| ).
ELSE.
ro_html->add( |<th colspan="3">@@ { is_diff_line-new_num } @@ { lv_beacon }</th>| ).
ENDIF.
ro_html->add( '</tr>' ).
ro_html->add( '</thead>' ).
ENDMETHOD.
METHOD render_content.
DATA: ls_diff_file LIKE LINE OF mt_diff_files,
lo_progress TYPE REF TO zcl_abapgit_progress.
CREATE OBJECT ro_html.
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( mt_diff_files ).
ro_html->add( |<div id="diff-list" data-repo-key="{ mv_repo_key }">| ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_js_error_banner( ) ).
LOOP AT mt_diff_files INTO ls_diff_file.
lo_progress->show(
iv_current = sy-tabix
iv_text = |Render Diff - { ls_diff_file-filename }| ).
ro_html->add( render_diff( ls_diff_file ) ).
ENDLOOP.
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_diff.
CREATE OBJECT ro_html.
ro_html->add( |<div class="diff" data-type="{ is_diff-type
}" data-changed-by="{ is_diff-changed_by
}" data-file="{ is_diff-path && is_diff-filename }">| ). "#EC NOTEXT
ro_html->add( render_diff_head( is_diff ) ).
" Content
IF is_diff-type <> 'binary'.
ro_html->add( '<div class="diff_content">' ). "#EC NOTEXT
ro_html->add( '<table class="diff_tab syntax-hl">' ). "#EC NOTEXT
ro_html->add( render_table_head( ) ).
ro_html->add( render_lines( is_diff ) ).
ro_html->add( '</table>' ). "#EC NOTEXT
ELSE.
ro_html->add( '<div class="diff_content paddings center grey">' ). "#EC NOTEXT
ro_html->add( 'The content seems to be binary.' ). "#EC NOTEXT
ro_html->add( 'Cannot display as diff.' ). "#EC NOTEXT
ENDIF.
ro_html->add( '</div>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ENDMETHOD.
METHOD render_diff_head.
DATA: ls_stats TYPE zif_abapgit_definitions=>ty_count.
CREATE OBJECT ro_html.
ro_html->add( '<div class="diff_head">' ). "#EC NOTEXT
IF is_diff-type <> 'binary'.
ls_stats = is_diff-o_diff->stats( ).
IF is_diff-fstate = c_fstate-both. " Merge stats into 'update' if both were changed
ls_stats-update = ls_stats-update + ls_stats-insert + ls_stats-delete.
CLEAR: ls_stats-insert, ls_stats-delete.
ENDIF.
ro_html->add( |<span class="diff_banner diff_ins">+ { ls_stats-insert }</span>| ).
ro_html->add( |<span class="diff_banner diff_del">- { ls_stats-delete }</span>| ).
ro_html->add( |<span class="diff_banner diff_upd">~ { ls_stats-update }</span>| ).
ENDIF.
ro_html->add( |<span class="diff_name">{ is_diff-path }{ is_diff-filename }</span>| ). "#EC NOTEXT
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_item_state(
iv_lstate = is_diff-lstate
iv_rstate = is_diff-rstate ) ).
IF is_diff-fstate = c_fstate-both AND mv_unified = abap_true.
ro_html->add( '<span class="attention pad-sides">Attention: Unified mode'
&& ' highlighting for MM assumes local file is newer ! </span>' ). "#EC NOTEXT
ENDIF.
ro_html->add( |<span class="diff_changed_by">last change by: <span class="user">{
is_diff-changed_by }</span></span>| ).
ro_html->add( '</div>' ). "#EC NOTEXT
ENDMETHOD.
METHOD render_lines.
DATA: lo_highlighter TYPE REF TO zcl_abapgit_syntax_highlighter,
lt_diffs TYPE zif_abapgit_definitions=>ty_diffs_tt,
lv_insert_nav TYPE abap_bool.
FIELD-SYMBOLS <ls_diff> LIKE LINE OF lt_diffs.
lo_highlighter = zcl_abapgit_syntax_highlighter=>create( is_diff-filename ).
CREATE OBJECT ro_html.
lt_diffs = is_diff-o_diff->get( ).
LOOP AT lt_diffs ASSIGNING <ls_diff>.
IF <ls_diff>-short = abap_false.
lv_insert_nav = abap_true.
CONTINUE.
ENDIF.
IF lv_insert_nav = abap_true. " Insert separator line with navigation
ro_html->add( render_beacon( is_diff_line = <ls_diff> is_diff = is_diff ) ).
lv_insert_nav = abap_false.
ENDIF.
IF lo_highlighter IS BOUND.
<ls_diff>-new = lo_highlighter->process_line( <ls_diff>-new ).
<ls_diff>-old = lo_highlighter->process_line( <ls_diff>-old ).
ELSE.
<ls_diff>-new = escape( val = <ls_diff>-new format = cl_abap_format=>e_html_attr ).
<ls_diff>-old = escape( val = <ls_diff>-old format = cl_abap_format=>e_html_attr ).
ENDIF.
CONDENSE <ls_diff>-new_num. "get rid of leading spaces
CONDENSE <ls_diff>-old_num.
IF mv_unified = abap_true.
ro_html->add( render_line_unified( is_diff_line = <ls_diff> ) ).
ELSE.
ro_html->add( render_line_split( is_diff_line = <ls_diff>
iv_fstate = is_diff-fstate ) ).
ENDIF.
ENDLOOP.
IF mv_unified = abap_true.
ro_html->add( render_line_unified( ) ). " Release delayed lines
ENDIF.
ENDMETHOD.
METHOD render_line_split.
DATA: lv_new TYPE string,
lv_old TYPE string,
lv_mark TYPE string,
lv_bg TYPE string.
CREATE OBJECT ro_html.
" New line
lv_mark = ` `.
IF iv_fstate = c_fstate-both OR is_diff_line-result = zif_abapgit_definitions=>c_diff-update.
lv_bg = ' diff_upd'.
lv_mark = `~`.
ELSEIF is_diff_line-result = zif_abapgit_definitions=>c_diff-insert.
lv_bg = ' diff_ins'.
lv_mark = `+`.
ENDIF.
lv_new = |<td class="num" line-num="{ is_diff_line-new_num }"></td>|
&& |<td class="code{ lv_bg }">{ lv_mark }{ is_diff_line-new }</td>|.
" Old line
CLEAR lv_bg.
lv_mark = ` `.
IF iv_fstate = c_fstate-both OR is_diff_line-result = zif_abapgit_definitions=>c_diff-update.
lv_bg = ' diff_upd'.
lv_mark = `~`.
ELSEIF is_diff_line-result = zif_abapgit_definitions=>c_diff-delete.
lv_bg = ' diff_del'.
lv_mark = `-`.
ENDIF.
lv_old = |<td class="num" line-num="{ is_diff_line-old_num }"></td>|
&& |<td class="code{ lv_bg }">{ lv_mark }{ is_diff_line-old }</td>|.
" render line, inverse sides if remote is newer
ro_html->add( '<tr>' ). "#EC NOTEXT
IF iv_fstate = c_fstate-remote. " Remote file leading changes
ro_html->add( lv_old ). " local
ro_html->add( lv_new ). " remote
ELSE. " Local leading changes or both were modified
ro_html->add( lv_new ). " local
ro_html->add( lv_old ). " remote
ENDIF.
ro_html->add( '</tr>' ). "#EC NOTEXT
ENDMETHOD.
METHOD render_line_unified.
FIELD-SYMBOLS <ls_diff_line> LIKE LINE OF mt_delayed_lines.
CREATE OBJECT ro_html.
" Release delayed subsequent update lines
IF is_diff_line-result <> zif_abapgit_definitions=>c_diff-update.
LOOP AT mt_delayed_lines ASSIGNING <ls_diff_line>.
ro_html->add( '<tr>' ). "#EC NOTEXT
ro_html->add( |<td class="num" line-num="{ <ls_diff_line>-old_num }"></td>|
&& |<td class="num" line-num=""></td>|
&& |<td class="code diff_del">-{ <ls_diff_line>-old }</td>| ).
ro_html->add( '</tr>' ). "#EC NOTEXT
ENDLOOP.
LOOP AT mt_delayed_lines ASSIGNING <ls_diff_line>.
ro_html->add( '<tr>' ). "#EC NOTEXT
ro_html->add( |<td class="num" line-num=""></td>|
&& |<td class="num" line-num="{ <ls_diff_line>-new_num }"></td>|
&& |<td class="code diff_ins">+{ <ls_diff_line>-new }</td>| ).
ro_html->add( '</tr>' ). "#EC NOTEXT
ENDLOOP.
CLEAR mt_delayed_lines.
ENDIF.
ro_html->add( '<tr>' ). "#EC NOTEXT
CASE is_diff_line-result.
WHEN zif_abapgit_definitions=>c_diff-update.
APPEND is_diff_line TO mt_delayed_lines. " Delay output of subsequent updates
WHEN zif_abapgit_definitions=>c_diff-insert.
ro_html->add( |<td class="num" line-num=""></td>|
&& |<td class="num" line-num="{ is_diff_line-new_num }"></td>|
&& |<td class="code diff_ins">+{ is_diff_line-new }</td>| ).
WHEN zif_abapgit_definitions=>c_diff-delete.
ro_html->add( |<td class="num" line-num="{ is_diff_line-old_num }"></td>|
&& |<td class="num" line-num=""></td>|
&& |<td class="code diff_del">-{ is_diff_line-old }</td>| ).
WHEN OTHERS. "none
ro_html->add( |<td class="num" line-num="{ is_diff_line-old_num }"></td>|
&& |<td class="num" line-num="{ is_diff_line-new_num }"></td>|
&& |<td class="code"> { is_diff_line-old }</td>| ).
ENDCASE.
ro_html->add( '</tr>' ). "#EC NOTEXT
ENDMETHOD.
METHOD render_table_head.
CREATE OBJECT ro_html.
ro_html->add( '<thead class="header">' ). "#EC NOTEXT
ro_html->add( '<tr>' ). "#EC NOTEXT
IF mv_unified = abap_true.
ro_html->add( '<th class="num">old</th>' ). "#EC NOTEXT
ro_html->add( '<th class="num">new</th>' ). "#EC NOTEXT
ro_html->add( '<th>code</th>' ). "#EC NOTEXT
ELSE.
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
ro_html->add( '<th>LOCAL</th>' ). "#EC NOTEXT
ro_html->add( '<th class="num"></th>' ). "#EC NOTEXT
ro_html->add( '<th>REMOTE</th>' ). "#EC NOTEXT
ENDIF.
ro_html->add( '</tr>' ). "#EC NOTEXT
ro_html->add( '</thead>' ). "#EC NOTEXT
ENDMETHOD.
METHOD scripts.
ro_html = super->scripts( ).
ro_html->add( 'var gHelper = new DiffHelper({' ).
ro_html->add( | seed: "{ mv_seed }",| ).
ro_html->add( ' ids: {' ).
ro_html->add( ' diffList: "diff-list",' ).
ro_html->add( ' filterMenu: "diff-filter",' ).
ro_html->add( ' }' ).
ro_html->add( '});' ).
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
CASE iv_action.
WHEN c_actions-toggle_unified. " Toggle file diplay
mv_unified = zcl_abapgit_persistence_user=>get_instance( )->toggle_diff_unified( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_DEBUGINFO IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
ms_control-page_title = 'DEBUG INFO'.
ENDMETHOD. " constructor.
METHOD render_content.
CREATE OBJECT ro_html.
ro_html->add( '<div id="debug_info" class="debug_container">' ).
ro_html->add( render_debug_info( ) ).
ro_html->add( render_supported_object_types( ) ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD render_debug_info.
DATA: lt_ver_tab TYPE filetable,
lv_rc TYPE i,
lv_gui_version TYPE string,
ls_version LIKE LINE OF lt_ver_tab.
cl_gui_frontend_services=>get_gui_version(
CHANGING version_table = lt_ver_tab rc = lv_rc
EXCEPTIONS OTHERS = 1 ).
READ TABLE lt_ver_tab INTO ls_version INDEX 1.
lv_gui_version = ls_version-filename.
READ TABLE lt_ver_tab INTO ls_version INDEX 2.
lv_gui_version = |{ lv_gui_version }.{ ls_version-filename }|.
CREATE OBJECT ro_html.
ro_html->add( |<p>abapGit version: { zif_abapgit_version=>gc_abap_version }</p>| ).
ro_html->add( |<p>XML version: { zif_abapgit_version=>gc_xml_version }</p>| ).
ro_html->add( |<p>GUI version: { lv_gui_version }</p>| ).
ro_html->add( |<p>LCL_TIME: { zcl_abapgit_time=>get( ) }</p>| ).
ro_html->add( |<p>SY time: { sy-datum } { sy-uzeit } { sy-tzone }</p>| ).
ENDMETHOD. "render_debug_info
METHOD render_supported_object_types.
DATA: lv_list TYPE string,
lt_types TYPE zcl_abapgit_objects=>ty_types_tt,
lv_type LIKE LINE OF lt_types.
lt_types = zcl_abapgit_objects=>supported_list( ).
LOOP AT lt_types INTO lv_type.
IF lv_list IS INITIAL.
lv_list = lv_type.
ELSE.
lv_list = lv_list && `, ` && lv_type.
ENDIF.
ENDLOOP.
rv_html = |<p>Supported objects: { lv_list }</p>|.
ENDMETHOD.
METHOD scripts.
ro_html = super->scripts( ).
ro_html->add( 'debugOutput("Browser: " + navigator.userAgent + ' &&
'"<br>Frontend time: " + new Date(), "debug_info");' ).
ENDMETHOD. "scripts
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_COMMIT IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
mo_repo = io_repo.
mo_stage = io_stage.
ms_control-page_title = 'COMMIT'.
ENDMETHOD.
METHOD parse_commit_request.
CONSTANTS: lc_replace TYPE string VALUE '<<new>>'.
DATA: lv_string TYPE string,
lt_fields TYPE tihttpnvp.
FIELD-SYMBOLS <lv_body> TYPE string.
CLEAR eg_fields.
CONCATENATE LINES OF it_postdata INTO lv_string.
REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_crlf IN lv_string WITH lc_replace.
REPLACE ALL OCCURRENCES OF zif_abapgit_definitions=>c_newline IN lv_string WITH lc_replace.
lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( lv_string ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'COMMITTER_NAME'
it_field = lt_fields
CHANGING
cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'COMMITTER_EMAIL'
it_field = lt_fields
CHANGING
cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'AUTHOR_NAME'
it_field = lt_fields
CHANGING
cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'AUTHOR_EMAIL'
it_field = lt_fields
CHANGING
cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'COMMENT'
it_field = lt_fields
CHANGING
cg_field = eg_fields ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'BODY'
it_field = lt_fields
CHANGING
cg_field = eg_fields ).
ASSIGN COMPONENT 'BODY' OF STRUCTURE eg_fields TO <lv_body>.
ASSERT <lv_body> IS ASSIGNED.
REPLACE ALL OCCURRENCES OF lc_replace IN <lv_body> WITH zif_abapgit_definitions=>c_newline.
ENDMETHOD.
METHOD render_content.
CREATE OBJECT ro_html.
ro_html->add( '<div class="repo">' ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top(
io_repo = mo_repo
iv_show_package = abap_false
iv_branch = mo_repo->get_branch_name( ) ) ).
ro_html->add( render_menu( ) ).
ro_html->add( render_form( ) ).
ro_html->add( render_stage( ) ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_form.
CONSTANTS: lc_body_col_max TYPE i VALUE 150.
DATA: li_user TYPE REF TO zif_abapgit_persist_user.
DATA: lv_user TYPE string.
DATA: lv_email TYPE string.
DATA: lv_s_param TYPE string.
DATA: lo_settings TYPE REF TO zcl_abapgit_settings.
DATA: lv_body_size TYPE i.
li_user = zcl_abapgit_persistence_user=>get_instance( ).
lv_user = li_user->get_repo_git_user_name( mo_repo->get_url( ) ).
IF lv_user IS INITIAL.
lv_user = li_user->get_default_git_user_name( ).
ENDIF.
IF lv_user IS INITIAL.
" get default from user master record
lv_user = zcl_abapgit_user_master_record=>get_instance( sy-uname )->get_name( ).
ENDIF.
lv_email = li_user->get_repo_git_user_email( mo_repo->get_url( ) ).
IF lv_email IS INITIAL.
lv_email = li_user->get_default_git_user_email( ).
ENDIF.
IF lv_email IS INITIAL.
" get default from user master record
lv_email = zcl_abapgit_user_master_record=>get_instance( sy-uname )->get_email( ).
ENDIF.
CREATE OBJECT ro_html.
ro_html->add( '<div class="form-container">' ).
ro_html->add( '<form id="commit_form" class="aligned-form"'
&& ' method="post" action="sapevent:commit_post">' ).
ro_html->add( render_text_input( iv_name = 'committer_name'
iv_label = 'committer name'
iv_value = lv_user ) ).
ro_html->add( render_text_input( iv_name = 'committer_email'
iv_label = 'committer e-mail'
iv_value = lv_email ) ).
lo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).
lv_s_param = lo_settings->get_commitmsg_comment_length( ).
ro_html->add( render_text_input( iv_name = 'comment'
iv_label = 'comment'
iv_max_length = lv_s_param ) ).
ro_html->add( '<div class="row">' ).
ro_html->add( '<label for="c-body">body</label>' ).
lv_body_size = lo_settings->get_commitmsg_body_size( ).
IF lv_body_size > lc_body_col_max.
lv_body_size = lc_body_col_max.
ENDIF.
ro_html->add( |<textarea id="c-body" name="body" rows="10" cols="| &&
|{ lv_body_size }"></textarea>| ).
ro_html->add( '<input type="submit" class="hidden-submit">' ).
ro_html->add( '</div>' ).
ro_html->add( '<div class="row">' ).
ro_html->add( '<span class="cell"></span>' ).
ro_html->add( '<span class="cell sub-title">Optionally,'
&& ' specify author (same as committer by default)</span>' ).
ro_html->add( '</div>' ).
ro_html->add( render_text_input( iv_name = 'author_name'
iv_label = 'author name' ) ).
ro_html->add( render_text_input( iv_name = 'author_email'
iv_label = 'author e-mail' ) ).
ro_html->add( '</form>' ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_menu.
DATA lo_toolbar TYPE REF TO zcl_abapgit_html_toolbar.
CREATE OBJECT ro_html.
CREATE OBJECT lo_toolbar.
lo_toolbar->add( iv_act = 'submitFormById(''commit_form'');'
iv_txt = 'Commit'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ) ##NO_TEXT.
lo_toolbar->add( iv_act = c_action-commit_cancel
iv_txt = 'Cancel'
iv_opt = zif_abapgit_definitions=>c_html_opt-cancel ) ##NO_TEXT.
ro_html->add( '<div class="paddings">' ).
ro_html->add( lo_toolbar->render( ) ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_stage.
DATA: lt_stage TYPE zcl_abapgit_stage=>ty_stage_tt.
FIELD-SYMBOLS: <ls_stage> LIKE LINE OF lt_stage.
CREATE OBJECT ro_html.
lt_stage = mo_stage->get_all( ).
ro_html->add( '<table class="stage_tab">' ).
ro_html->add( '<thead>' ).
ro_html->add( '<tr>').
ro_html->add( '<th colspan="2">Staged files</th>').
ro_html->add( '</tr>' ).
ro_html->add( '</thead>' ).
ro_html->add( '<tbody>' ).
LOOP AT lt_stage ASSIGNING <ls_stage>.
ro_html->add( '<tr>' ).
ro_html->add( '<td class="method">' ).
ro_html->add( zcl_abapgit_stage=>method_description( <ls_stage>-method ) ).
ro_html->add( '</td>' ).
ro_html->add( '<td>' ).
ro_html->add( <ls_stage>-file-path && <ls_stage>-file-filename ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
ENDLOOP.
ro_html->add( '</tbody>' ).
ro_html->add( '</table>' ).
ENDMETHOD.
METHOD render_text_input.
DATA lv_attrs TYPE string.
CREATE OBJECT ro_html.
IF iv_value IS NOT INITIAL.
lv_attrs = | value="{ iv_value }"|.
ENDIF.
IF iv_max_length IS NOT INITIAL.
lv_attrs = | maxlength="{ iv_max_length }"|.
ENDIF.
ro_html->add( '<div class="row">' ).
ro_html->add( |<label for="{ iv_name }">{ iv_label }</label>| ).
ro_html->add( |<input id="{ iv_name }" name="{ iv_name }" type="text"{ lv_attrs }>| ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD scripts.
ro_html = super->scripts( ).
ro_html->add( 'setInitialFocus("comment");' ).
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA: ls_commit TYPE zcl_abapgit_services_git=>ty_commit_fields.
CASE iv_action.
WHEN c_action-commit_post.
parse_commit_request(
EXPORTING it_postdata = it_postdata
IMPORTING eg_fields = ls_commit ).
ls_commit-repo_key = mo_repo->get_key( ).
zcl_abapgit_services_git=>commit( is_commit = ls_commit
io_repo = mo_repo
io_stage = mo_stage ).
ev_state = zif_abapgit_definitions=>c_event_state-go_back_to_bookmark.
WHEN c_action-commit_cancel.
ev_state = zif_abapgit_definitions=>c_event_state-go_back.
ENDCASE.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION.
METHOD build_menu.
DATA: lv_opt TYPE c LENGTH 1.
CREATE OBJECT ro_menu.
ro_menu->add( iv_txt = 'Re-Run'
iv_act = c_actions-rerun
iv_cur = abap_false ) ##NO_TEXT.
IF is_stage_allowed( ) = abap_false.
lv_opt = zif_abapgit_definitions=>c_html_opt-crossout.
ENDIF.
IF mo_repo->is_offline( ) = abap_true.
RETURN.
ENDIF.
IF mo_stage IS BOUND.
" Staging info already available, we can directly
" offer to commit
ro_menu->add( iv_txt = 'Commit'
iv_act = c_actions-commit
iv_cur = abap_false
iv_opt = lv_opt ) ##NO_TEXT.
ELSE.
ro_menu->add( iv_txt = 'Stage'
iv_act = c_actions-stage
iv_cur = abap_false
iv_opt = lv_opt ) ##NO_TEXT.
ENDIF.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
mo_repo ?= io_repo.
mo_stage = io_stage.
ms_control-page_title = 'Code Inspector'.
run_code_inspector( ).
ENDMETHOD. " constructor.
METHOD has_inspection_errors.
READ TABLE mt_result TRANSPORTING NO FIELDS
WITH KEY kind = 'E'.
rv_has_inspection_errors = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD is_stage_allowed.
rv_is_stage_allowed = boolc( NOT ( mo_repo->get_local_settings( )-block_commit = abap_true
AND has_inspection_errors( ) = abap_true ) ).
ENDMETHOD.
METHOD jump.
DATA: lo_test TYPE REF TO cl_ci_test_root,
li_code_inspector TYPE REF TO zif_abapgit_code_inspector,
ls_info TYPE scir_rest,
lo_result TYPE REF TO cl_ci_result_root,
lv_check_variant_name TYPE sci_chkv,
lv_package TYPE devclass.
FIELD-SYMBOLS: <ls_result> TYPE scir_alvlist.
READ TABLE mt_result WITH KEY objtype = is_item-obj_type
objname = is_item-obj_name
ASSIGNING <ls_result>.
ASSERT sy-subrc = 0.
lv_package = mo_repo->get_package( ).
lv_check_variant_name = mo_repo->get_local_settings( )-code_inspector_check_variant.
li_code_inspector = zcl_abapgit_factory=>get_code_inspector(
iv_package = lv_package
iv_check_variant_name = lv_check_variant_name ).
" see SCI_LCL_DYNP_530 / HANDLE_DOUBLE_CLICK
MOVE-CORRESPONDING <ls_result> TO ls_info.
TRY.
lo_test ?= cl_ci_tests=>get_test_ref( <ls_result>-test ).
CATCH cx_root.
zcx_abapgit_exception=>raise( |Jump to object not supported in your NW release| ).
ENDTRY.
lo_result = lo_test->get_result_node( <ls_result>-kind ).
lo_result->set_info( ls_info ).
lo_result->if_ci_test~navigate( ).
ENDMETHOD.
METHOD render_content.
DATA: lv_check_variant TYPE sci_chkv,
lv_class TYPE string,
lv_line TYPE string.
FIELD-SYMBOLS: <ls_result> TYPE scir_alvlist.
CREATE OBJECT ro_html.
lv_check_variant = mo_repo->get_local_settings( )-code_inspector_check_variant.
IF lv_check_variant IS INITIAL.
ro_html->add( |No check variant maintained in repo settings.| ).
RETURN.
ENDIF.
ro_html->add( '<div class="toc"><br/>' ).
ro_html->add( |Code inspector check variant: {
mo_repo->get_local_settings( )-code_inspector_check_variant
}<br/>| ).
IF lines( mt_result ) = 0.
ro_html->add( '<br/><div class="success">No code inspector findings</div>' ).
ENDIF.
ro_html->add( |<br/>| ).
LOOP AT mt_result ASSIGNING <ls_result>.
ro_html->add( '<div>' ).
ro_html->add_a( iv_txt = |{ <ls_result>-objtype } { <ls_result>-objname }|
iv_act = |{ <ls_result>-objtype }{ <ls_result>-objname }|
iv_typ = zif_abapgit_definitions=>c_action_type-sapevent ).
ro_html->add( '</div>' ).
CASE <ls_result>-kind.
WHEN 'E'.
lv_class = 'error'.
WHEN 'W'.
lv_class = 'warning'.
WHEN OTHERS.
lv_class = 'grey'.
ENDCASE.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_OUTPUT'
EXPORTING
input = <ls_result>-line
IMPORTING
output = lv_line.
ro_html->add( |<div class="{ lv_class }">Line { lv_line }: { <ls_result>-text }</div><br>| ).
ENDLOOP.
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD run_code_inspector.
mt_result = mo_repo->run_code_inspector( ).
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA: lo_repo_online TYPE REF TO zcl_abapgit_repo_online,
ls_item TYPE zif_abapgit_definitions=>ty_item.
CASE iv_action.
WHEN c_actions-stage.
lo_repo_online ?= mo_repo.
IF is_stage_allowed( ) = abap_true.
" we need to refresh as the source might have changed
lo_repo_online->refresh( ).
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_stage
EXPORTING
io_repo = lo_repo_online.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
ELSE.
ei_page = me.
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
ENDIF.
WHEN c_actions-commit.
lo_repo_online ?= mo_repo.
IF is_stage_allowed( ) = abap_true.
CREATE OBJECT ei_page TYPE zcl_abapgit_gui_page_commit
EXPORTING
io_repo = lo_repo_online
io_stage = mo_stage.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
ELSE.
ei_page = me.
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
ENDIF.
WHEN c_actions-rerun.
run_code_inspector( ).
ei_page = me.
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN OTHERS.
ls_item-obj_type = iv_action(4).
ls_item-obj_name = iv_action+4(*).
jump( ls_item ).
ev_state = zif_abapgit_definitions=>c_event_state-no_more_act.
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_gui_page~render.
ms_control-page_menu = build_menu( ).
ro_html = super->zif_abapgit_gui_page~render( ).
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
DATA: ls_hotkey_action LIKE LINE OF rt_hotkey_actions.
ls_hotkey_action-name = |Code Inspector: Stage|.
ls_hotkey_action-action = c_actions-stage.
ls_hotkey_action-default_hotkey = |s|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ls_hotkey_action-name = |Code Inspector: Re-Run|.
ls_hotkey_action-action = c_actions-rerun.
ls_hotkey_action-default_hotkey = |r|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page_boverview IMPLEMENTATION.
METHOD body.
DATA: lv_tag TYPE string.
FIELD-SYMBOLS: <ls_commit> LIKE LINE OF mt_commits,
<ls_create> LIKE LINE OF <ls_commit>-create.
CREATE OBJECT ro_html.
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top(
io_repo = mo_repo
iv_show_package = abap_false
iv_show_branch = abap_false ) ).
ro_html->add( '<br>' ).
ro_html->add( '<br>' ).
ro_html->add( render_merge( ) ).
ro_html->add( '<br>' ).
ro_html->add( build_menu( )->render( ) ).
ro_html->add( '<canvas id="gitGraph"></canvas>' ).
ro_html->add( '<script type="text/javascript" src="https://cdnjs.' &&
'cloudflare.com/ajax/libs/gitgraph.js/1.12.0/gitgraph.min.js">' &&
'</script>' ) ##NO_TEXT.
ro_html->add( '<script type="text/javascript">' ).
ro_html->add( 'var myTemplateConfig = {' ).
ro_html->add( 'colors: [ "#979797", "#008fb5", "#f1c109", "'
&& '#095256", "#087F8C", "#5AAA95", "#86A873", "#BB9F06" ],' ) ##NO_TEXT.
ro_html->add( 'branch: {' ).
ro_html->add( ' lineWidth: 8,' ).
ro_html->add( ' spacingX: 50' ).
ro_html->add( '},' ).
ro_html->add( 'commit: {' ).
ro_html->add( ' spacingY: -40,' ).
ro_html->add( ' dot: { size: 12 },' ).
ro_html->add( ' message: { font: "normal 14pt Arial" }' ).
ro_html->add( '}' ).
ro_html->add( '};' ).
ro_html->add( 'var gitgraph = new GitGraph({' ).
ro_html->add( ' template: myTemplateConfig,' ).
ro_html->add( ' orientation: "vertical-reverse"' ).
ro_html->add( '});' ).
LOOP AT mt_commits ASSIGNING <ls_commit>.
IF sy-tabix = 1.
ro_html->add( |var {
escape_branch( <ls_commit>-branch ) } = gitgraph.branch("{
<ls_commit>-branch }");| ).
ENDIF.
IF <ls_commit>-compressed = abap_true.
ro_html->add( |{ escape_branch( <ls_commit>-branch ) }.commit(\{message: "{
escape_message( <ls_commit>-message )
}", dotColor: "black", dotSize: 15, messageHashDisplay: false, messageAuthorDisplay: false\});| ).
ELSEIF <ls_commit>-merge IS INITIAL.
" gitgraph doesn't support multiple tags per commit yet.
" Therefore we concatenate them.
" https://github.com/nicoespeon/gitgraph.js/issues/143
lv_tag = concat_lines_of( table = <ls_commit>-tags
sep = ` | ` ).
ro_html->add( |{ escape_branch( <ls_commit>-branch ) }.commit(\{message: "{
escape_message( <ls_commit>-message ) }", author: "{
<ls_commit>-author }", sha1: "{
<ls_commit>-sha1(7) }", tag: "{ lv_tag }"\});| ).
ELSE.
ro_html->add( |{ escape_branch( <ls_commit>-merge ) }.merge({
escape_branch( <ls_commit>-branch ) }, \{message: "{
escape_message( <ls_commit>-message ) }", author: "{
<ls_commit>-author }", sha1: "{
<ls_commit>-sha1(7) }"\});| ).
ENDIF.
LOOP AT <ls_commit>-create ASSIGNING <ls_create>.
ro_html->add( |var { escape_branch( <ls_create>-name ) } = {
escape_branch( <ls_create>-parent ) }.branch("{
<ls_create>-name }");| ).
ENDLOOP.
ENDLOOP.
ro_html->add( '</script>' ).
ENDMETHOD.
METHOD build_menu.
CREATE OBJECT ro_menu.
IF mv_compress = abap_true.
ro_menu->add(
iv_txt = 'Uncompress Graph'
iv_act = c_actions-uncompress ) ##NO_TEXT.
ELSE.
ro_menu->add(
iv_txt = 'Compress Graph'
iv_act = c_actions-compress ) ##NO_TEXT.
ENDIF.
ro_menu->add( iv_txt = 'Refresh' iv_act = c_actions-refresh ) ##NO_TEXT.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
ms_control-page_title = 'BRANCH_OVERVIEW'.
mo_repo = io_repo.
refresh( ).
ENDMETHOD.
METHOD decode_merge.
DATA: lv_string TYPE string,
lt_fields TYPE tihttpnvp.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
CONCATENATE LINES OF it_postdata INTO lv_string.
lt_fields = zcl_abapgit_html_action_utils=>parse_fields( lv_string ).
READ TABLE lt_fields ASSIGNING <ls_field> WITH KEY name = 'source' ##NO_TEXT.
ASSERT sy-subrc = 0.
rs_merge-source = <ls_field>-value.
READ TABLE lt_fields ASSIGNING <ls_field> WITH KEY name = 'target' ##NO_TEXT.
ASSERT sy-subrc = 0.
rs_merge-target = <ls_field>-value.
ENDMETHOD.
METHOD escape_branch.
rv_string = iv_string.
TRANSLATE rv_string USING '-_._'.
rv_string = |branch_{ rv_string }|.
ENDMETHOD.
METHOD escape_message.
rv_string = iv_string.
REPLACE ALL OCCURRENCES OF '"' IN rv_string WITH '\"'.
ENDMETHOD.
METHOD form_select.
DATA: lv_name TYPE string,
lt_branches TYPE zif_abapgit_definitions=>ty_git_branch_list_tt.
FIELD-SYMBOLS: <ls_branch> LIKE LINE OF lt_branches.
CREATE OBJECT ro_html.
lt_branches = mi_branch_overview->get_branches( ).
ro_html->add( |<select name="{ iv_name }">| ).
LOOP AT lt_branches ASSIGNING <ls_branch>.
lv_name = <ls_branch>-name+11.
ro_html->add( |<option value="{ lv_name }">{ lv_name }</option>| ).
ENDLOOP.
ro_html->add( '</select>' ).
ENDMETHOD.
METHOD refresh.
mi_branch_overview = zcl_abapgit_factory=>get_branch_overview( mo_repo ).
mt_commits = mi_branch_overview->get_commits( ).
IF mv_compress = abap_true.
mt_commits = mi_branch_overview->compress( mt_commits ).
ENDIF.
ENDMETHOD.
METHOD render_content.
CREATE OBJECT ro_html.
ro_html->add( '<div id="toc">' ).
ro_html->add( body( ) ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD render_merge.
CREATE OBJECT ro_html.
ro_html->add( '<form id="commit_form" method="post" action="sapevent:merge">' ).
ro_html->add( 'Merge' ) ##NO_TEXT.
ro_html->add( form_select( 'source' ) ) ##NO_TEXT.
ro_html->add( 'into' ) ##NO_TEXT.
ro_html->add( form_select( 'target' ) ) ##NO_TEXT.
ro_html->add( '<input type="submit" value="Submit">' ).
ro_html->add( '</form>' ).
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA: ls_merge TYPE ty_merge,
lo_merge TYPE REF TO zcl_abapgit_gui_page_merge.
CASE iv_action.
WHEN c_actions-refresh.
refresh( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_actions-uncompress.
mv_compress = abap_false.
refresh( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_actions-compress.
mv_compress = abap_true.
refresh( ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
WHEN c_actions-merge.
ls_merge = decode_merge( it_postdata ).
CREATE OBJECT lo_merge
EXPORTING
io_repo = mo_repo
iv_source = ls_merge-source
iv_target = ls_merge-target.
ei_page = lo_merge.
ev_state = zif_abapgit_definitions=>c_event_state-new_page.
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_BKG_RUN IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
ms_control-page_title = 'BACKGROUND_RUN'.
ENDMETHOD. " constructor.
METHOD render_content.
DATA: lv_text LIKE LINE OF mt_text.
run( ).
CREATE OBJECT ro_html.
ro_html->add( '<div id="toc">' ).
LOOP AT mt_text INTO lv_text.
ro_html->add( '<pre>' && lv_text && '</pre><br>' ).
ENDLOOP.
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD run.
DATA: lx_error TYPE REF TO zcx_abapgit_exception,
lv_text TYPE string,
lv_line TYPE i VALUE 1.
TRY.
zcl_abapgit_background=>run( ).
DO.
READ LINE lv_line LINE VALUE INTO lv_text.
IF sy-subrc <> 0.
EXIT.
ENDIF.
APPEND lv_text TO mt_text.
lv_line = lv_line + 1.
ENDDO.
CATCH zcx_abapgit_exception INTO lx_error.
APPEND lx_error->get_text( ) TO mt_text.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
RETURN.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_BKG IMPLEMENTATION.
METHOD build_menu.
CREATE OBJECT ro_menu.
ro_menu->add( iv_txt = 'Run background logic'
iv_act = zif_abapgit_definitions=>c_action-go_background_run ) ##NO_TEXT.
ENDMETHOD.
METHOD constructor.
super->constructor( ).
mv_key = iv_key.
ms_control-page_title = 'BACKGROUND'.
ms_control-page_menu = build_menu( ).
ENDMETHOD.
METHOD decode.
DATA: lt_fields TYPE tihttpnvp.
FIELD-SYMBOLS: <ls_setting> LIKE LINE OF rs_fields-settings.
rs_fields-key = mv_key.
lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( iv_getdata ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'METHOD'
it_field = lt_fields
CHANGING
cg_field = rs_fields ).
IF rs_fields-method IS INITIAL.
RETURN.
ENDIF.
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'USERNAME'
it_field = lt_fields
CHANGING
cg_field = rs_fields ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'PASSWORD'
it_field = lt_fields
CHANGING
cg_field = rs_fields ).
CALL METHOD (rs_fields-method)=>zif_abapgit_background~get_settings
CHANGING
ct_settings = rs_fields-settings.
LOOP AT rs_fields-settings ASSIGNING <ls_setting>.
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = <ls_setting>-key
it_field = lt_fields
CHANGING
cg_field = <ls_setting>-value ).
ENDLOOP.
ASSERT NOT rs_fields IS INITIAL.
ENDMETHOD.
METHOD read_persist.
DATA: lo_per TYPE REF TO zcl_abapgit_persist_background,
lt_per TYPE zcl_abapgit_persist_background=>tt_background.
CREATE OBJECT lo_per.
lt_per = lo_per->list( ).
READ TABLE lt_per INTO rs_persist WITH KEY key = io_repo->get_key( ).
IF sy-subrc <> 0.
CLEAR rs_persist.
ENDIF.
ENDMETHOD.
METHOD render.
DATA: lo_repo TYPE REF TO zcl_abapgit_repo_online,
ls_per TYPE zcl_abapgit_persist_background=>ty_background.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( mv_key ).
ls_per = read_persist( lo_repo ).
CREATE OBJECT ro_html.
ro_html->add( '<div id="toc">' ).
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_repo_top( lo_repo ) ).
ro_html->add( '<br>' ).
ro_html->add( render_methods( ls_per ) ).
ro_html->add( '<u>HTTP Authentication, optional</u><br>' ) ##NO_TEXT.
ro_html->add( '(password will be saved in clear text)<br>' ) ##NO_TEXT.
ro_html->add( '<table>' ).
ro_html->add( '<tr>' ).
ro_html->add( '<td>Username:</td>' ).
ro_html->add( '<td><input type="text" name="username" value="' &&
ls_per-username && '"></td>' ).
ro_html->add( '</tr>' ).
ro_html->add( '<tr>' ).
ro_html->add( '<td>Password:</td>' ).
ro_html->add( '<td><input type="text" name="password" value="' &&
ls_per-password && '"></td>' ).
ro_html->add( '</tr>' ).
ro_html->add( '</table>' ).
ro_html->add( '<br>' ).
ro_html->add( render_settings( ls_per ) ).
ro_html->add( '<br>' ).
ro_html->add( '<input type="submit" value="Save">' ).
ro_html->add( '</form>' ).
ro_html->add( '<br>' ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_content.
CREATE OBJECT ro_html.
ro_html->add( render( ) ).
ENDMETHOD.
METHOD render_methods.
DATA: lt_methods TYPE zcl_abapgit_background=>ty_methods_tt,
ls_method LIKE LINE OF lt_methods,
lv_checked TYPE string.
CREATE OBJECT ro_html.
lt_methods = zcl_abapgit_background=>list_methods( ).
ro_html->add( '<u>Method</u><br>' ) ##NO_TEXT.
ro_html->add( |<form method="get" action="sapevent:{ zif_abapgit_definitions=>c_action-bg_update }">| ).
IF is_per-method IS INITIAL.
lv_checked = ' checked' ##NO_TEXT.
ENDIF.
ro_html->add( '<input type="radio" name="method" value=""' &&
lv_checked && '>Do nothing<br>' ) ##NO_TEXT.
LOOP AT lt_methods INTO ls_method.
CLEAR lv_checked.
IF is_per-method = ls_method-class.
lv_checked = ' checked' ##NO_TEXT.
ENDIF.
ro_html->add( '<input type="radio" name="method" value="' &&
ls_method-class && '"' &&
lv_checked && '>' &&
ls_method-description && '<br>' ) ##NO_TEXT.
ENDLOOP.
ro_html->add( '<br>' ).
ENDMETHOD.
METHOD render_settings.
DATA: lt_settings LIKE is_per-settings,
ls_setting LIKE LINE OF lt_settings.
CREATE OBJECT ro_html.
IF is_per-method IS INITIAL.
RETURN.
ENDIF.
lt_settings = is_per-settings.
IF is_per-method <> 'push' AND is_per-method <> 'pull' AND is_per-method <> 'nothing'.
CALL METHOD (is_per-method)=>zif_abapgit_background~get_settings
CHANGING
ct_settings = lt_settings.
ENDIF.
IF lines( lt_settings ) = 0.
RETURN.
ENDIF.
ro_html->add( '<table>' ).
LOOP AT lt_settings INTO ls_setting.
ro_html->add( '<tr>' ).
ro_html->add( '<td>' && ls_setting-key && ':</td>' ).
ro_html->add( '<td><input type="text" name="' &&
ls_setting-key && '" value="' &&
ls_setting-value && '"></td>' ).
ro_html->add( '</tr>' ).
ENDLOOP.
ro_html->add( '</table>' ).
ENDMETHOD.
METHOD update.
DATA lo_persistence TYPE REF TO zcl_abapgit_persist_background.
CREATE OBJECT lo_persistence.
IF is_bg_task-method IS INITIAL.
lo_persistence->delete( is_bg_task-key ).
ELSE.
lo_persistence->modify( is_bg_task ).
ENDIF.
MESSAGE 'Saved' TYPE 'S' ##NO_TEXT.
COMMIT WORK.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
CASE iv_action.
WHEN zif_abapgit_definitions=>c_action-bg_update.
update( decode( iv_getdata ) ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
ENDCASE.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_gui_page IMPLEMENTATION.
METHOD add_hotkeys.
DATA: lv_json TYPE string,
lt_hotkeys TYPE zif_abapgit_definitions=>tty_hotkey.
FIELD-SYMBOLS: <ls_hotkey> TYPE zif_abapgit_definitions=>ty_hotkey.
lt_hotkeys = zcl_abapgit_hotkeys=>get_relevant_hotkeys_for_page( me ).
lv_json = `{`.
LOOP AT lt_hotkeys ASSIGNING <ls_hotkey>.
IF sy-tabix > 1.
lv_json = lv_json && |,|.
ENDIF.
lv_json = lv_json && | "{ <ls_hotkey>-sequence }" : "{ <ls_hotkey>-action }" |.
ENDLOOP.
lv_json = lv_json && `}`.
io_html->add( |setKeyBindings({ lv_json });| ).
ENDMETHOD.
METHOD footer.
CREATE OBJECT ro_html.
ro_html->add( '<div id="footer">' ). "#EC NOTEXT
ro_html->add( '<img src="img/logo" alt="logo">' ). "#EC NOTEXT
ro_html->add( '<table class="w100"><tr>' ). "#EC NOTEXT
ro_html->add( '<td class="w40"></td>' ). "#EC NOTEXT
ro_html->add( |<td><span class="version">{ zif_abapgit_version=>gc_abap_version }</span></td>| ). "#EC NOTEXT
ro_html->add( '<td id="debug-output" class="w40"></td>' ). "#EC NOTEXT
ro_html->add( '</tr></table>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ENDMETHOD. "footer
METHOD get_hotkey_actions.
" these are the global shortcuts active on all pages
DATA: ls_hotkey_action LIKE LINE OF rt_hotkey_actions.
ls_hotkey_action-name = |Global: Show hotkeys|.
ls_hotkey_action-action = c_global_page_action-showhotkeys.
ls_hotkey_action-default_hotkey = |?|.
INSERT ls_hotkey_action INTO TABLE rt_hotkey_actions.
ENDMETHOD.
METHOD html_head.
CREATE OBJECT ro_html.
ro_html->add( '<head>' ). "#EC NOTEXT
ro_html->add( '<meta http-equiv="content-type" content="text/html; charset=utf-8">' ). "#EC NOTEXT
ro_html->add( '<meta http-equiv="X-UA-Compatible" content="IE=11,10,9,8" />' ). "#EC NOTEXT
ro_html->add( '<title>abapGit</title>' ). "#EC NOTEXT
ro_html->add( '<link rel="stylesheet" type="text/css" href="css/common.css">' ).
ro_html->add( '<script type="text/javascript" src="js/common.js"></script>' ). "#EC NOTEXT
ro_html->add( zcl_abapgit_gui_asset_manager=>get_webfont_link( ) ). " Web fonts
ro_html->add( '</head>' ). "#EC NOTEXT
ENDMETHOD. "html_head
METHOD link_hints.
DATA: lo_settings TYPE REF TO zcl_abapgit_settings,
lv_link_hint_key TYPE char01,
lv_background_color TYPE string.
lo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).
lv_link_hint_key = lo_settings->get_link_hint_key( ).
lv_background_color = lo_settings->get_link_hint_background_color( ).
IF lo_settings->get_link_hints_enabled( ) = abap_true
AND lv_link_hint_key IS NOT INITIAL.
io_html->add( |setLinkHints("{ lv_link_hint_key }","{ lv_background_color }");| ).
io_html->add( |setInitialFocusWithQuerySelector('a span', true);| ).
io_html->add( |enableArrowListNavigation();| ).
ENDIF.
ENDMETHOD.
METHOD redirect.
CREATE OBJECT ro_html.
ro_html->add( '<!DOCTYPE html>' ). "#EC NOTEXT
ro_html->add( '<html>' ). "#EC NOTEXT
ro_html->add( '<head>' ). "#EC NOTEXT
ro_html->add( |<meta http-equiv="refresh" content="0; url={
ms_control-redirect_url }">| ). "#EC NOTEXT
ro_html->add( '</head>' ). "#EC NOTEXT
ro_html->add( '</html>' ). "#EC NOTEXT
ENDMETHOD.
METHOD render_hotkey_overview.
CREATE OBJECT ro_html.
ro_html->add( zcl_abapgit_gui_chunk_lib=>render_hotkey_overview( ) ).
ENDMETHOD.
METHOD scripts.
CREATE OBJECT ro_html.
link_hints( ro_html ).
add_hotkeys( ro_html ).
ENDMETHOD. "scripts
METHOD title.
CREATE OBJECT ro_html.
ro_html->add( '<div id="header">' ). "#EC NOTEXT
ro_html->add( '<table class="w100"><tr>' ). "#EC NOTEXT
ro_html->add( |<td class="logo">{
zcl_abapgit_html=>a( iv_txt = '<img src="img/logo" alt="logo">'
iv_id = 'abapGitLogo'
iv_act = zif_abapgit_definitions=>c_action-abapgit_home )
}</td>| ). "#EC NOTEXT
ro_html->add( |<td><span class="page_title"> ► {
ms_control-page_title
}</span></td>| ). "#EC NOTEXT
IF ms_control-page_menu IS BOUND.
ro_html->add( '<td class="right">' ). "#EC NOTEXT
ro_html->add( ms_control-page_menu->render( iv_right = abap_true ) ).
ro_html->add( '</td>' ). "#EC NOTEXT
ENDIF.
ro_html->add( '</tr></table>' ). "#EC NOTEXT
ro_html->add( '</div>' ). "#EC NOTEXT
ENDMETHOD. "render page title
METHOD zif_abapgit_gui_page~on_event.
ev_state = zif_abapgit_definitions=>c_event_state-not_handled.
ENDMETHOD. "lif_gui_page~on_event
METHOD zif_abapgit_gui_page~render.
DATA lo_script TYPE REF TO zcl_abapgit_html.
" Redirect
IF ms_control-redirect_url IS NOT INITIAL.
ro_html = redirect( ).
RETURN.
ENDIF.
" Real page
CREATE OBJECT ro_html.
ro_html->add( '<!DOCTYPE html>' ). "#EC NOTEXT
ro_html->add( '<html>' ). "#EC NOTEXT
ro_html->add( html_head( ) ).
ro_html->add( '<body>' ). "#EC NOTEXT
ro_html->add( title( ) ).
ro_html->add( render_hotkey_overview( ) ).
ro_html->add( render_content( ) ).
ro_html->add( footer( ) ).
ro_html->add( '</body>' ). "#EC NOTEXT
lo_script = scripts( ).
IF lo_script IS BOUND AND lo_script->is_empty( ) = abap_false.
ro_html->add( '<script type="text/javascript">' ).
ro_html->add( lo_script ).
ro_html->add( 'confirmInitialized();' ).
ro_html->add( '</script>' ).
ENDIF.
ro_html->add( '</html>' ). "#EC NOTEXT
ENDMETHOD. " lif_gui_page~render.
ENDCLASS.
CLASS zcl_abapgit_gui_chunk_lib IMPLEMENTATION.
METHOD render_branch_span.
DATA: lv_text TYPE string,
lv_class TYPE string.
lv_text = zcl_abapgit_git_branch_list=>get_display_name( iv_branch ).
IF zcl_abapgit_git_branch_list=>get_type( iv_branch ) = zif_abapgit_definitions=>c_git_branch_type-branch.
lv_class = 'branch branch_branch'.
ELSE.
lv_class = 'branch'.
ENDIF.
CREATE OBJECT ro_html.
ro_html->add( |<span class="{ lv_class }">| ).
ro_html->add_icon( iv_name = 'git-branch/darkgrey' iv_hint = 'Current branch' ).
IF iv_interactive = abap_true.
ro_html->add_a( iv_act = |{ zif_abapgit_definitions=>c_action-git_branch_switch }?{ io_repo->get_key( ) }|
iv_txt = lv_text ).
ELSE.
ro_html->add( lv_text ).
ENDIF.
ro_html->add( '</span>' ).
ENDMETHOD. "render_branch_span
METHOD render_error.
DATA lv_error TYPE string.
CREATE OBJECT ro_html.
IF ix_error IS BOUND.
lv_error = ix_error->get_text( ).
ELSE.
lv_error = iv_error.
ENDIF.
ro_html->add( '<div class="dummydiv error">' ).
ro_html->add( |{ zcl_abapgit_html=>icon( 'alert/red' ) } Error: { lv_error }| ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_error
METHOD render_hotkey_overview.
DATA: lv_display TYPE string,
lt_hotkeys TYPE zif_abapgit_definitions=>tty_hotkey,
lt_actions TYPE zif_abapgit_gui_page_hotkey=>tty_hotkey_action,
lo_settings TYPE REF TO zcl_abapgit_settings.
FIELD-SYMBOLS: <ls_hotkey> TYPE zif_abapgit_definitions=>ty_hotkey,
<ls_action> LIKE LINE OF lt_actions.
lo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).
lt_hotkeys = lo_settings->get_hotkeys( ).
lt_actions = zcl_abapgit_hotkeys=>get_default_hotkeys_from_pages( ).
CREATE OBJECT ro_html.
lv_display = 'display:none'.
ro_html->add( |<div id="hotkeys" class="news" style="{ lv_display }">| ).
ro_html->add( '<div class="headbar title">Hotkeys'
&& '<div class="float-right">'
&& zcl_abapgit_html=>a(
iv_txt = '❌'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_act = 'closeHotkeyOverview()'
iv_class = 'close-btn' )
&& '</div></div>' ).
READ TABLE lt_hotkeys ASSIGNING <ls_hotkey>
WITH KEY action = zcl_abapgit_gui_page=>c_global_page_action-showhotkeys.
IF sy-subrc = 0.
ro_html->add( |<div class="paddings">Close window with '{ <ls_hotkey>-sequence }' |
&& |or upper right corner X</div>| ).
ENDIF.
" Generate hotkeys
ro_html->add( |<div class="newslist">| ).
ro_html->add( '<table>' ).
LOOP AT lt_hotkeys ASSIGNING <ls_hotkey>.
READ TABLE lt_actions ASSIGNING <ls_action>
WITH TABLE KEY action
COMPONENTS action = <ls_hotkey>-action.
IF sy-subrc = 0.
ro_html->add( '<tr>' ).
ro_html->add( |<td>{ <ls_hotkey>-sequence }</td><td>-</td><td>{ <ls_action>-name }</td>| ).
ro_html->add( '</tr>' ).
ENDIF.
ENDLOOP.
ro_html->add( '</table>' ).
ro_html->add( '</div>' ).
ro_html->add( '</div>' ).
ENDMETHOD.
METHOD render_item_state.
DATA: lv_system TYPE string.
FIELD-SYMBOLS <lv_state> TYPE char1.
rv_html = '<span class="state-block">'.
DO 2 TIMES.
CASE sy-index.
WHEN 1.
ASSIGN iv_lstate TO <lv_state>.
lv_system = 'Local:'.
WHEN 2.
ASSIGN iv_rstate TO <lv_state>.
lv_system = 'Remote:'.
ENDCASE.
CASE <lv_state>.
WHEN zif_abapgit_definitions=>c_state-unchanged. "None or unchanged
IF iv_lstate = zif_abapgit_definitions=>c_state-added OR iv_rstate = zif_abapgit_definitions=>c_state-added.
rv_html = rv_html && |<span class="none" title="{ lv_system } Not exists">X</span>|.
ELSE.
rv_html = rv_html && |<span class="none" title="{ lv_system } No changes"> </span>|.
ENDIF.
WHEN zif_abapgit_definitions=>c_state-modified. "Changed
rv_html = rv_html && |<span class="changed" title="{ lv_system } Modified">M</span>|.
WHEN zif_abapgit_definitions=>c_state-added. "Added new
rv_html = rv_html && |<span class="added" title="{ lv_system } Added new">A</span>|.
WHEN zif_abapgit_definitions=>c_state-mixed. "Multiple changes (multifile)
rv_html = rv_html && |<span class="mixed" title="{ lv_system } Multiple changes">■</span>|.
WHEN zif_abapgit_definitions=>c_state-deleted. "Deleted
rv_html = rv_html && |<span class="deleted" title="{ lv_system } Deleted">D</span>|.
ENDCASE.
ENDDO.
rv_html = rv_html && '</span>'.
ENDMETHOD. "render_item_state
METHOD render_js_error_banner.
CREATE OBJECT ro_html.
ro_html->add( '<div id="js-error-banner" class="dummydiv error">' ).
ro_html->add( |{ zcl_abapgit_html=>icon( 'alert/red' ) }| &&
' If this does not disappear soon,' &&
' then there is a JS init error, please log an issue' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_js_error_stub
METHOD render_news.
DATA: lv_text TYPE string,
lv_display TYPE string,
lt_log TYPE zcl_abapgit_news=>tt_log.
FIELD-SYMBOLS: <ls_line> LIKE LINE OF lt_log.
CREATE OBJECT ro_html.
IF io_news IS NOT BOUND OR io_news->has_news( ) = abap_false.
RETURN.
ENDIF.
lt_log = io_news->get_log( ).
IF io_news->has_unseen( ) = abap_false.
lv_display = 'display:none'.
ENDIF.
ro_html->add( |<div id="news" class="news" style="{ lv_display }">| ).
ro_html->add( '<div class="headbar title">Announcement of the latest changes'
&& '<div class="float-right">'
&& zcl_abapgit_html=>a(
iv_txt = '❌'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_act = 'displayNews()'
iv_class = 'close-btn' )
&& '</div></div>' ).
IF io_news->has_important( ) = abap_true.
ro_html->add( '<div class="headbar important">'
&& zcl_abapgit_html=>icon( iv_name = 'alert' iv_class = 'pad-right' )
&& 'Please note changes marked with "!"'
&& '</div>' ).
ENDIF.
" Generate news
ro_html->add( |<div class="newslist">| ).
LOOP AT lt_log ASSIGNING <ls_line>.
IF <ls_line>-is_header = abap_true.
IF <ls_line>-pos_to_cur > 0.
lv_text = <ls_line>-text && '<span class="version-marker update">update</span>'.
ELSEIF <ls_line>-pos_to_cur = 0.
lv_text = <ls_line>-text && '<span class="version-marker">current</span>'.
ELSE. " < 0
lv_text = <ls_line>-text.
ENDIF.
ro_html->add( |<h1>{ lv_text }</h1>| ).
ELSE.
ro_html->add( |<li>{ <ls_line>-text }</li>| ).
ENDIF.
ENDLOOP.
ro_html->add( '</div>' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_news
METHOD render_repo_top.
DATA: lo_repo_online TYPE REF TO zcl_abapgit_repo_online,
lo_pback TYPE REF TO zcl_abapgit_persist_background,
lv_hint TYPE string,
lv_icon TYPE string.
CREATE OBJECT ro_html.
CREATE OBJECT lo_pback.
IF io_repo->is_offline( ) = abap_true.
lv_icon = 'plug/darkgrey' ##NO_TEXT.
lv_hint = 'Offline repository' ##NO_TEXT.
ELSE.
lv_icon = 'cloud-upload/blue' ##NO_TEXT.
lv_hint = 'On-line repository' ##NO_TEXT.
ENDIF.
ro_html->add( '<table class="w100"><tr>' ).
ro_html->add( '<td class="repo_name">' ).
" Repo type and name
ro_html->add_icon( iv_name = lv_icon iv_hint = lv_hint ).
ro_html->add( |<span class="name">{ io_repo->get_name( ) }</span>| ).
IF io_repo->is_offline( ) = abap_false.
lo_repo_online ?= io_repo.
ro_html->add( |<span class="url">{ lo_repo_online->get_url( ) }</span>| ).
ENDIF.
" News
IF io_news IS BOUND AND io_news->has_news( ) = abap_true.
IF io_news->has_updates( ) = abap_true.
lv_icon = 'arrow-up/warning'.
ELSE.
lv_icon = 'arrow-up/grey80'.
ENDIF.
ro_html->add_a( iv_act = 'displayNews()'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_txt = zcl_abapgit_html=>icon( iv_name = lv_icon
iv_class = 'pad-sides'
iv_hint = 'Display changelog' ) ).
ENDIF.
ro_html->add( '</td>' ).
ro_html->add( '<td class="repo_attr right">' ).
" Fav
IF abap_true = zcl_abapgit_persistence_user=>get_instance( )->is_favorite_repo( io_repo->get_key( ) ).
lv_icon = 'star/blue' ##NO_TEXT.
ELSE.
lv_icon = 'star/grey' ##NO_TEXT.
ENDIF.
ro_html->add_a( iv_act = |{ zif_abapgit_definitions=>c_action-repo_toggle_fav }?{ io_repo->get_key( ) }|
iv_txt = zcl_abapgit_html=>icon( iv_name = lv_icon
iv_class = 'pad-sides'
iv_hint = 'Click to toggle favorite' ) ).
" BG
IF lo_pback->exists( io_repo->get_key( ) ) = abap_true.
ro_html->add( '<span class="bg_marker" title="background">BG</span>' ).
ENDIF.
" Write protect
IF io_repo->get_local_settings( )-write_protected = abap_true.
ro_html->add_icon( iv_name = 'lock/darkgrey' iv_hint = 'Locked from pulls' ).
ENDIF.
" Branch
IF io_repo->is_offline( ) = abap_false.
lo_repo_online ?= io_repo.
IF iv_show_branch = abap_true.
IF iv_branch IS INITIAL.
ro_html->add( render_branch_span( iv_branch = lo_repo_online->get_branch_name( )
io_repo = lo_repo_online
iv_interactive = iv_interactive_branch ) ).
ELSE.
ro_html->add( render_branch_span( iv_branch = iv_branch
io_repo = lo_repo_online
iv_interactive = iv_interactive_branch ) ).
ENDIF.
ENDIF.
ENDIF.
" Package
IF iv_show_package = abap_true.
ro_html->add_icon( iv_name = 'package/darkgrey' iv_hint = 'SAP package' ).
ro_html->add( '<span>' ).
ro_html->add_a( iv_txt = io_repo->get_package( )
iv_act = |{ zif_abapgit_definitions=>c_action-jump_pkg }?{ io_repo->get_package( ) }| ).
ro_html->add( '</span>' ).
ENDIF.
ro_html->add( '</td>' ).
ro_html->add( '</tr></table>' ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_ASSET_MANAGER IMPLEMENTATION.
METHOD get_asset.
DATA: lv_asset_name TYPE string,
lv_mime_name TYPE wwwdatatab-objid.
lv_asset_name = to_upper( iv_asset_name ).
CASE lv_asset_name.
WHEN 'CSS_COMMON'.
lv_mime_name = 'ZABAPGIT_CSS_COMMON'.
WHEN 'JS_COMMON'.
lv_mime_name = 'ZABAPGIT_JS_COMMON'.
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Improper resource name: { iv_asset_name }| ).
ENDCASE.
" Inline is default (for older AG snapshots to work)
rv_data = get_inline_asset( lv_asset_name ).
IF rv_data IS INITIAL.
rv_data = get_mime_asset( lv_mime_name ). " Get MIME object
ENDIF.
IF rv_data IS INITIAL.
zcx_abapgit_exception=>raise( |Failed to get GUI resource: { iv_asset_name }| ).
ENDIF.
ENDMETHOD. " get_asset.
METHOD get_images.
FIELD-SYMBOLS <ls_image> LIKE LINE OF rt_images.
rt_images = get_inline_images( ).
" Convert to xstring
LOOP AT rt_images ASSIGNING <ls_image>.
CALL FUNCTION 'SSFC_BASE64_DECODE'
EXPORTING
b64data = <ls_image>-base64
IMPORTING
bindata = <ls_image>-content
EXCEPTIONS
OTHERS = 1.
ASSERT sy-subrc = 0. " Image data error
ENDLOOP.
ENDMETHOD. " get_images.
METHOD get_inline_asset.
DEFINE _inline.
APPEND &1 TO lt_data.
END-OF-DEFINITION.
DATA: lt_data TYPE zif_abapgit_definitions=>ty_string_tt,
lv_str TYPE string.
CASE iv_asset_name.
WHEN 'CSS_COMMON'.
_inline '/*'.
_inline ' * ABAPGIT COMMON CSS'.
_inline ' */'.
_inline ''.
_inline '/* GLOBALS */'.
_inline ''.
_inline 'body {'.
_inline ' font-family: Arial,Helvetica,sans-serif;'.
_inline ' font-size: 12pt;'.
_inline ' background: #E8E8E8;'.
_inline '}'.
_inline ''.
_inline 'a, a:visited {'.
_inline ' color: #4078c0;'.
_inline ' text-decoration: none;'.
_inline '}'.
_inline ''.
_inline 'a:hover, a:active {'.
_inline ' cursor: pointer;'.
_inline ' text-decoration: underline;'.
_inline '}'.
_inline ''.
_inline '#abapGitLogo {'.
_inline ' outline: none;'.
_inline '}'.
_inline ''.
_inline 'img { border: 0px; vertical-align: middle; }'.
_inline 'table { border-collapse: collapse; }'.
_inline 'pre { display: inline; }'.
_inline 'sup {'.
_inline ' vertical-align: top;'.
_inline ' position: relative;'.
_inline ' top: -0.5em;'.
_inline ' font-size: 75%;'.
_inline '}'.
_inline ''.
_inline 'input, textarea, select {'.
_inline ' padding: 3px 6px;'.
_inline ' border: 1px solid #ddd;'.
_inline '}'.
_inline ''.
_inline 'input:focus, textarea:focus {'.
_inline ' border: 1px solid #8cadd9;'.
_inline '}'.
_inline ''.
_inline '/* COLOR PALETTE */'.
_inline '.grey { color: lightgrey !important; }'.
_inline '.grey70 { color: #b3b3b3 !important; }'.
_inline '.grey80 { color: #ccc !important; }'.
_inline '.bgorange { background-color: orange; }'.
_inline '.darkgrey { color: #808080 !important; }'.
_inline '.attention { color: red !important; }'.
_inline '.error { color: #d41919 !important; }'.
_inline '.warning { color: #efb301 !important; }'.
_inline '.success { color: green !important; }'.
_inline '.blue { color: #5e8dc9 !important; }'.
_inline '.red { color: red !important; }'.
_inline '.white { color: white !important; }'.
_inline ''.
_inline '/* MODIFIERS */'.
_inline '.emphasis { font-weight: bold !important; }'.
_inline '.crossout { text-decoration: line-through !important; }'.
_inline '.right { text-align:right; }'.
_inline '.center { text-align:center; }'.
_inline '.paddings { padding: 0.5em 0.5em; }'.
_inline '.pad-sides { padding-left: 0.3em; padding-right: 0.3em; }'.
_inline '.margin-v5 { margin-top: 0.5em; margin-bottom: 0.5em; }'.
_inline '.indent5em { padding-left: 0.5em; }'.
_inline '.pad4px { padding: 4px; }'.
_inline '.w100 { width: 100%; }'.
_inline '.w40 { width: 40%; }'.
_inline '.float-right { float: right; }'.
_inline '.pad-right { padding-right: 6px; }'.
_inline ''.
_inline '/* STRUCTURE DIVS, HEADER & FOOTER */'.
_inline 'div#header {'.
_inline ' padding: 0.5em 0.5em;'.
_inline ' border-bottom: 3px double lightgrey;'.
_inline '}'.
_inline 'div#header td.logo { width: 164px; }'.
_inline 'div#header td:not(.logo) { padding-top: 11px; } /* align with logo H */'.
_inline 'div#header span.page_title {'.
_inline ' font-weight: normal;'.
_inline ' font-size: 18pt;'.
_inline ' color: #bbb;'.
_inline ' padding-left: 0.4em;'.
_inline '}'.
_inline ''.
_inline 'div#toc {'.
_inline ' padding: 0.5em 1em;'.
_inline ' background-color: #f2f2f2;'.
_inline '}'.
_inline 'div#toc .favorites a { opacity: 0.5; }'.
_inline 'div#toc .favorites:hover a { opacity: 1; }'.
_inline ''.
_inline 'div#footer {'.
_inline ' padding: 0.5em 1em;'.
_inline ' border-top: 3px double lightgrey;'.
_inline ' text-align: center;'.
_inline '}'.
_inline 'div#footer span.version {'.
_inline ' display: block;'.
_inline ' color: grey;'.
_inline ' margin-top: 0.3em;'.
_inline '}'.
_inline ''.
_inline '#debug-output {'.
_inline ' text-align: right;'.
_inline ' padding-right: 0.5em;'.
_inline ' color: #ccc;'.
_inline ' font-style: italic;'.
_inline ' font-size: small;'.
_inline '}'.
_inline ''.
_inline 'div.dummydiv {'.
_inline ' background-color: #f2f2f2;'.
_inline ' padding: 0.5em 1em;'.
_inline ' text-align: center;'.
_inline '}'.
_inline ''.
_inline '/* ERROR LOG */'.
_inline ''.
_inline 'div.log {'.
_inline ' padding: 6px;'.
_inline ' margin: 4px;'.
_inline ' background-color: #fee6e6;'.
_inline ' border: 1px #fdcece solid;'.
_inline ' border-radius: 4px;'.
_inline '}'.
_inline 'div.log > span { display:block; }'.
_inline 'div.log .octicon { padding-right: 6px; }'.
_inline ''.
_inline '/* REPOSITORY */'.
_inline 'div.repo {'.
_inline ' margin-top: 3px;'.
_inline ' background-color: #f2f2f2;'.
_inline ' padding: 0.5em 1em 0.5em 1em;'.
_inline ' position: relative;'.
_inline '}'.
_inline '.repo_name span.name {'.
_inline ' font-weight: bold;'.
_inline ' color: #333;'.
_inline ' font-size: 14pt;'.
_inline '}'.
_inline '.repo_name span.url {'.
_inline ' color: #ccc;'.
_inline ' font-size: 12pt;'.
_inline ' margin-left: 0.5em;'.
_inline '}'.
_inline '.repo_name img {'.
_inline ' vertical-align: baseline;'.
_inline ' margin: 0 5px 0 5px;'.
_inline '}'.
_inline '.repo_attr {'.
_inline ' color: grey;'.
_inline ' font-size: 12pt;'.
_inline '}'.
_inline '.repo_attr span {'.
_inline ' margin-left: 0.2em;'.
_inline ' margin-right: 0.5em;'.
_inline '}'.
_inline '.repo_attr span.bg_marker {'.
_inline ' border: 1px solid #d2d2d2;'.
_inline ' border-radius: 3px;'.
_inline ' background: #d8d8d8;'.
_inline ' color: #fff;'.
_inline ' font-size: 8pt;'.
_inline ' padding: 4px 2px 3px 2px;'.
_inline '}'.
_inline '.repo_attr span.branch {'.
_inline ' padding: 2px 4px;'.
_inline ' border: 1px solid #d9d9d9;'.
_inline ' border-radius: 4px;'.
_inline ' background-color: #e2e2e2;'.
_inline '}'.
_inline '.repo_attr span.branch_head {'.
_inline ' border-color: #d8dff3;'.
_inline ' background-color: #eceff9;'.
_inline '}'.
_inline '.repo_attr span.branch_branch {'.
_inline ' border-color: #e7d9b1;'.
_inline ' background-color: #f8f0d8;'.
_inline '}'.
_inline ''.
_inline '/* MISC AND REFACTOR */'.
_inline '.hidden-submit {'.
_inline ' border: 0 none;'.
_inline ' height: 0;'.
_inline ' width: 0;'.
_inline ' padding: 0;'.
_inline ' margin: 0;'.
_inline ' overflow: hidden;'.
_inline '}'.
_inline ''.
_inline '/* REPOSITORY TABLE*/'.
_inline 'div.repo_container {'.
_inline ' position: relative;'.
_inline '}'.
_inline 'table.repo_tab {'.
_inline ' border: 1px solid #DDD;'.
_inline ' border-radius: 3px;'.
_inline ' background: #fff;'.
_inline ' width: 100%;'.
_inline '}'.
_inline '.repo_tab td {'.
_inline ' border-top: 1px solid #eee;'.
_inline ' vertical-align: middle;'.
_inline ' color: #333;'.
_inline ' padding-top: 2px;'.
_inline ' padding-bottom: 2px;'.
_inline '}'.
_inline '.repo_tab td.icon {'.
_inline ' width: 32px;'.
_inline ' text-align: center;'.
_inline '}'.
_inline '.repo_tab td.type {'.
_inline ' width: 3em;'.
_inline '}'.
_inline '.repo_tab td.object {'.
_inline ' padding-left: 0.5em;'.
_inline '}'.
_inline '.repo_tab td.files {'.
_inline ' padding-left: 0.5em;'.
_inline '}'.
_inline '.repo_tab td.cmd {'.
_inline ' text-align: right;'.
_inline ' padding-left: 0.5em;'.
_inline ' padding-right: 0.7em;'.
_inline '}'.
_inline '.repo_tab tr.unsupported { color: lightgrey; }'.
_inline '.repo_tab tr.modified { background: #fbf7e9; }'.
_inline '.repo_tab tr:first-child td { border-top: 0px; }'.
_inline '.repo_tab td.current_dir { color: #ccc; }'.
_inline '.repo_tab td.cmd span.state-block {'.
_inline ' margin-left: 1em;'.
_inline ' font-family: Consolas, Lucida Console, Courier, monospace;'.
_inline ' font-size: x-small;'.
_inline ' vertical-align: 13%;'.
_inline ' display: inline-block;'.
_inline ' text-align: center;'.
_inline '}'.
_inline '.repo_tab td.cmd span.state-block span {'.
_inline ' display: inline-block;'.
_inline ' padding: 0px 2px;'.
_inline ' border: 1px solid #000;'.
_inline '}'.
_inline '.repo_tab td.cmd span.state-block span.added {'.
_inline ' background-color: #69ad74;'.
_inline ' border-color: #579e64;'.
_inline ' color: white;'.
_inline '}'.
_inline '.repo_tab td.cmd span.state-block span.changed {'.
_inline ' background-color: #e0c150;'.
_inline ' border-color: #d4af25;'.
_inline ' color: white;'.
_inline '}'.
_inline '.repo_tab td.cmd span.state-block span.mixed {'.
_inline ' background-color: #e0c150;'.
_inline ' border-color: #579e64;'.
_inline ' color: #69ad74;'.
_inline '}'.
_inline '.repo_tab td.cmd span.state-block span.deleted {'.
_inline ' background-color: #c76861;'.
_inline ' border-color: #b8605a;'.
_inline ' color: white;'.
_inline '}'.
_inline '.repo_tab td.cmd span.state-block span.none {'.
_inline ' background-color: #e8e8e8;'.
_inline ' border-color: #dbdbdb;'.
_inline ' color: #c8c8c8;'.
_inline '}'.
_inline ''.
_inline '/* STAGE */'.
_inline 'div.stage-container { width: 850px; }'.
_inline 'input.stage-filter { width: 18em; }'.
_inline ''.
_inline '.stage_tab {'.
_inline ' border: 1px solid #DDD;'.
_inline ' background: #fff;'.
_inline ' margin-top: 0.2em;'.
_inline '}'.
_inline '.stage_tab td {'.
_inline ' border-top: 1px solid #eee;'.
_inline ' color: #333;'.
_inline ' vertical-align: middle;'.
_inline ' padding: 2px 0.5em;'.
_inline '}'.
_inline '.stage_tab th {'.
_inline ' color: #BBB;'.
_inline ' text-align: left;'.
_inline ' font-weight: normal;'.
_inline ' background-color: #edf2f9;'.
_inline ' padding: 4px 0.5em;'.
_inline '}'.
_inline '.stage_tab td.status {'.
_inline ' width: 2em;'.
_inline ' text-align: center;'.
_inline ' color: #ccc;'.
_inline ' background-color: #fafafa;'.
_inline '}'.
_inline '.stage_tab td.highlight {'.
_inline ' color: #444 !important;'.
_inline ' font-weight: bold;'.
_inline '}'.
_inline ''.
_inline '.stage_tab td.cmd { cursor: pointer; }'.
_inline '.stage_tab td.cmd a { padding: 0px 4px; }'.
_inline '.stage_tab th.cmd a { padding: 0px 4px; }'.
_inline '.stage_tab td.method { color: #ccc; }'.
_inline '.stage_tab td.user { color: #aaa; }'.
_inline '.stage_tab td.type { color: #aaa; }'.
_inline '.stage_tab tbody tr:first-child td { padding-top: 0.5em; }'.
_inline '.stage_tab tbody tr:last-child td { padding-bottom: 0.5em; }'.
_inline '.stage_tab mark {'.
_inline ' color: white;'.
_inline ' background-color: #79a0d2;'.
_inline '}'.
_inline ''.
_inline '/* COMMIT */'.
_inline 'div.form-container {'.
_inline ' background-color: #F8F8F8;'.
_inline ' padding: 1em 1em;'.
_inline '}'.
_inline ''.
_inline 'form.aligned-form {'.
_inline ' display: table;'.
_inline ' border-spacing: 2px;'.
_inline '}'.
_inline ''.
_inline 'form.aligned-form label {'.
_inline ' color: #BBB;'.
_inline ' padding-right: 1em;'.
_inline ' vertical-align: middle;'.
_inline '}'.
_inline ''.
_inline 'form.aligned-form select {'.
_inline ' padding-right: 1em;'.
_inline ' vertical-align: middle;'.
_inline '}'.
_inline ''.
_inline 'form.aligned-form span.sub-title {'.
_inline ' color: #BBB;'.
_inline ' font-size: smaller;'.
_inline ' padding-top: 8px;'.
_inline '}'.
_inline ''.
_inline 'form.aligned-form div.row { display: table-row; }'.
_inline 'form.aligned-form label { display: table-cell; }'.
_inline 'form.aligned-form input { display: table-cell; }'.
_inline 'form.aligned-form input[type="text"] { width: 25em; }'.
_inline 'form.aligned-form span.cell { display: table-cell; }'.
_inline ''.
_inline '/* SETTINGS STYLES */'.
_inline 'div.settings_container {'.
_inline ' padding: 0.5em;'.
_inline ' font-size: 10pt;'.
_inline ' color: #444;'.
_inline ' background-color: #f2f2f2;'.
_inline '}'.
_inline ''.
_inline 'div.settings_section {'.
_inline ' margin-left:50px'.
_inline '}'.
_inline ''.
_inline '/* DIFF */'.
_inline 'div.diff {'.
_inline ' background-color: #f2f2f2;'.
_inline ' padding: 0.7em'.
_inline '}'.
_inline 'div.diff_head {'.
_inline ' padding-bottom: 0.7em;'.
_inline '}'.
_inline 'span.diff_name {'.
_inline ' padding-left: 0.5em;'.
_inline ' color: grey;'.
_inline '}'.
_inline 'span.diff_changed_by {'.
_inline ' color: grey;'.
_inline ' float: right;'.
_inline '}'.
_inline 'span.diff_changed_by span.user {'.
_inline ' border-radius: 3px;'.
_inline ' border: solid 1px #c2d4ea;'.
_inline ' background-color: #d9e4f2;'.
_inline ' padding: 1px 0.4em;'.
_inline '}'.
_inline 'span.diff_name strong {'.
_inline ' color: #333;'.
_inline '}'.
_inline 'span.diff_banner {'.
_inline ' border-style: solid;'.
_inline ' border-width: 1px;'.
_inline ' border-radius: 3px;'.
_inline ' padding-left: 0.3em;'.
_inline ' padding-right: 0.3em;'.
_inline '}'.
_inline '.diff_ins {'.
_inline ' border-color: #abf2ab;'.
_inline ' background-color: #e0ffe0;'.
_inline '}'.
_inline '.diff_del {'.
_inline ' border-color: #ff667d;'.
_inline ' background-color: #ffccd4;'.
_inline '}'.
_inline '.diff_upd {'.
_inline ' border-color: #dada00;'.
_inline ' background-color: #ffffcc;'.
_inline '}'.
_inline 'div.diff_content {'.
_inline ' background: #fff;'.
_inline ' border-top: 1px solid #DDD;'.
_inline ' border-bottom: 1px solid #DDD;'.
_inline '}'.
_inline 'div.diff_head span.state-block {'.
_inline ' margin-left: 0.5em;'.
_inline ' font-family: Consolas, Lucida Console, Courier, monospace;'.
_inline ' display: inline-block;'.
_inline ' text-align: center;'.
_inline '}'.
_inline 'div.diff_head span.state-block span {'.
_inline ' display: inline-block;'.
_inline ' padding: 0px 4px;'.
_inline ' border: 1px solid #000;'.
_inline '}'.
_inline 'div.diff_head span.state-block span.added {'.
_inline ' background-color: #69ad74;'.
_inline ' border-color: #579e64;'.
_inline ' color: white;'.
_inline '}'.
_inline 'div.diff_head span.state-block span.changed {'.
_inline ' background-color: #e0c150;'.
_inline ' border-color: #d4af25;'.
_inline ' color: white;'.
_inline '}'.
_inline 'div.diff_head span.state-block span.mixed {'.
_inline ' background-color: #e0c150;'.
_inline ' border-color: #579e64;'.
_inline ' color: #69ad74;'.
_inline '}'.
_inline 'div.diff_head span.state-block span.deleted {'.
_inline ' background-color: #c76861;'.
_inline ' border-color: #b8605a;'.
_inline ' color: white;'.
_inline '}'.
_inline 'div.diff_head span.state-block span.none {'.
_inline ' background-color: #e8e8e8;'.
_inline ' border-color: #dbdbdb;'.
_inline ' color: #c8c8c8;'.
_inline '}'.
_inline ''.
_inline '/* DIFF TABLE */'.
_inline 'table.diff_tab {'.
_inline ' font-family: Consolas, Courier, monospace;'.
_inline ' font-size: 10pt;'.
_inline ' width: 100%;'.
_inline '}'.
_inline 'table.diff_tab td,th {'.
_inline ' color: #444;'.
_inline ' padding-left: 0.5em;'.
_inline ' padding-right: 0.5em;'.
_inline '}'.
_inline 'table.diff_tab th {'.
_inline ' text-align: left;'.
_inline ' font-weight: normal;'.
_inline ' padding-top: 3px;'.
_inline ' padding-bottom: 3px;'.
_inline '}'.
_inline 'table.diff_tab thead.header th {'.
_inline ' color: #EEE;'.
_inline ' background-color: #BBB;'.
_inline ' text-align: left;'.
_inline ' font-weight: bold;'.
_inline ' padding-left: 0.5em;'.
_inline ' font-size: 9pt;'.
_inline '}'.
_inline 'table.diff_tab thead.nav_line {'.
_inline ' background-color: #edf2f9;'.
_inline '}'.
_inline 'table.diff_tab thead.nav_line th {'.
_inline ' color: #bbb;'.
_inline '}'.
_inline 'table.diff_tab td.num, th.num {'.
_inline ' width: 1%;'.
_inline ' min-width: 2em;'.
_inline ' padding-right: 8px;'.
_inline ' padding-left: 8px;'.
_inline ' text-align: right !important;'.
_inline ' color: #ccc;'.
_inline ' border-left: 1px solid #eee;'.
_inline ' border-right: 1px solid #eee;'.
_inline ' -ms-user-select: none;'.
_inline ' user-select: none;'.
_inline '}'.
_inline 'table.diff_tab td.num::before {'.
_inline ' content: attr(line-num);'.
_inline '}'.
_inline 'table.diff_tab code {'.
_inline ' font-family: inherit;'.
_inline ' white-space: pre;'.
_inline '}'.
_inline 'table.diff_tab td.code {'.
_inline ' word-wrap: break-word;'.
_inline ' white-space: pre-wrap;'.
_inline ' overflow: visible;'.
_inline '}'.
_inline ''.
_inline 'table.diff_tab tbody tr:first-child td { padding-top: 0.5em; }'.
_inline 'table.diff_tab tbody tr:last-child td { padding-bottom: 0.5em; }'.
_inline ''.
_inline '/* STYLES for Syntax Highlighting */'.
_inline '.syntax-hl span.keyword { color: #0a69ce; }'.
_inline '.syntax-hl span.text { color: #48ce4f; }'.
_inline '.syntax-hl span.comment { color: #808080; font-style: italic; }'.
_inline '.syntax-hl span.xml_tag { color: #457ce3; }'.
_inline '.syntax-hl span.attr { color: #b777fb; }'.
_inline '.syntax-hl span.attr_val { color: #7a02f9; }'.
_inline ''.
_inline '/* DEBUG INFO STYLES */'.
_inline 'div.debug_container {'.
_inline ' padding: 0.5em;'.
_inline ' font-size: 10pt;'.
_inline ' color: #444;'.
_inline ' font-family: Consolas, Courier, monospace;'.
_inline '}'.
_inline ''.
_inline 'div.debug_container p {'.
_inline ' margin: 0px;'.
_inline '}'.
_inline ''.
_inline '/* DB ENTRIES */'.
_inline 'div.db_list {'.
_inline ' background-color: #fff;'.
_inline ' padding: 0.5em;'.
_inline '}'.
_inline ''.
_inline 'table.db_tab pre {'.
_inline ' display: inline-block;'.
_inline ' overflow: hidden;'.
_inline ' word-wrap:break-word;'.
_inline ' white-space: pre-wrap;'.
_inline ' margin: 0px;'.
_inline ' width: 30em;'.
_inline '}'.
_inline ''.
_inline 'table.db_tab tr.firstrow td { padding-top: 0.5em; }'.
_inline 'table.db_tab th {'.
_inline ' color: #888888;'.
_inline ' text-align: left;'.
_inline ' padding: 0.5em;'.
_inline ' border-bottom: 1px #ddd solid;'.
_inline '}'.
_inline 'table.db_tab td {'.
_inline ' color: #333;'.
_inline ' padding: 4px 8px;'.
_inline ' vertical-align: middle;'.
_inline '}'.
_inline 'table.db_tab td.data {'.
_inline ' color: #888;'.
_inline ' font-style: italic;'.
_inline '}'.
_inline ''.
_inline 'table.db_tab tbody tr:hover, tr:active {'.
_inline ' background-color: #f4f4f4;'.
_inline '}'.
_inline ''.
_inline '/* DB ENTRY DISPLAY */'.
_inline 'div.db_entry {'.
_inline ' background-color: #f2f2f2;'.
_inline ' padding: 0.5em;'.
_inline '}'.
_inline ''.
_inline 'div.db_entry pre {'.
_inline ' display: block;'.
_inline ' font-size: 10pt;'.
_inline ' overflow: hidden;'.
_inline ' word-wrap:break-word;'.
_inline ' white-space: pre-wrap;'.
_inline ' background-color: #fcfcfc;'.
_inline ' border: 1px #eaeaea solid;'.
_inline ' border-radius: 3px;'.
_inline ' padding: 0.5em;'.
_inline ' margin: 0.5em 0em;'.
_inline ' width: 60em;'.
_inline '}'.
_inline ''.
_inline 'div.db_entry table.toolbar {'.
_inline ' width: 50em;'.
_inline '}'.
_inline ''.
_inline 'table.tag {'.
_inline ' display: inline-block;'.
_inline ' border: 1px #b3c1cc solid;'.
_inline ' background-color: #eee;'.
_inline ' border-radius: 3px;'.
_inline ' margin-right: 0.5em;'.
_inline '}'.
_inline 'table.tag td { padding: 0.2em 0.5em; }'.
_inline 'table.tag td.label { background-color: #b3c1cc; }'.
_inline ''.
_inline '/* DB ENTRY DISPLAY */'.
_inline 'div.db_entry textarea { margin: 0.5em 0em; }'.
_inline 'table.tag {'.
_inline ' display: inline-block;'.
_inline ' border: 1px #b3c1cc solid;'.
_inline ' background-color: #eee;'.
_inline ' border-radius: 3px;'.
_inline ' margin-right: 0.5em;'.
_inline '}'.
_inline 'table.tag td { padding: 0.2em 0.5em; }'.
_inline 'table.tag td.label { background-color: #b3c1cc; }'.
_inline ''.
_inline '/* TUTORIAL */'.
_inline ''.
_inline 'div.tutorial {'.
_inline ' margin-top: 3px;'.
_inline ' background-color: #f2f2f2;'.
_inline ' padding: 0.5em 1em 0.5em 1em;'.
_inline '}'.
_inline ''.
_inline 'div.tutorial hr { border-color: #CCC; }'.
_inline 'div.tutorial li { margin: 2px 0px }'.
_inline 'div.tutorial h1 {'.
_inline ' font-size: 18pt;'.
_inline ' color: #404040;'.
_inline '}'.
_inline 'div.tutorial h2 {'.
_inline ' font-size: 14pt;'.
_inline ' color: #404040;'.
_inline '}'.
_inline ''.
_inline '/* NEW MENU */'.
_inline '/* Special credits to example at https://codepen.io/philhoyt/pen/ujHzd */'.
_inline '/* container div, aligned left, '.
_inline ' but with .float-right modifier alignes right */'.
_inline '.nav-container ul'.
_inline '{'.
_inline ' list-style: none;'.
_inline ' position: relative;'.
_inline ' float: left;'.
_inline ' margin: 0;'.
_inline ' padding: 0;'.
_inline '}'.
_inline '.nav-container.float-right ul { float: right; }'.
_inline ''.
_inline '.nav-container ul a'.
_inline '{'.
_inline ' display: block;'.
_inline ' text-decoration: none;'.
_inline ' line-height: 30px;'.
_inline ' padding: 0 12px;'.
_inline '}'.
_inline ''.
_inline '/* clearfix https://css-tricks.com/snippets/css/clear-fix/ */'.
_inline '.nav-container:after { clear: both; display: block; content: ""; } '.
_inline ''.
_inline '/* submenues align to left or right border of the active item'.
_inline ' depending on .float-right modifier */'.
_inline '.nav-container ul li'.
_inline '{'.
_inline ' position: relative;'.
_inline ' float: left;'.
_inline ' margin: 0;'.
_inline ' padding: 0;'.
_inline '}'.
_inline '.nav-container.float-right ul ul { left: auto; right: 0; }'.
_inline ''.
_inline '.nav-container ul li.current-menu-item { font-weight: 700; }'.
_inline '.nav-container ul li.block ul { display: block; }'.
_inline '.nav-container ul li:hover > ul { display: block; }'.
_inline '.nav-container ul ul li:hover { background-color: #f6f6f6; }'.
_inline ''.
_inline '/* special selection style for 1st level items (see also .corner below) */'.
_inline '.nav-container > ul > li:hover > a { '.
_inline ' background-color: rgba(255, 255, 255, 0.5); '.
_inline '}'.
_inline ''.
_inline '.nav-container ul ul'.
_inline '{'.
_inline ' display: none;'.
_inline ' position: absolute;'.
_inline ' top: 100%;'.
_inline ' left: 0;'.
_inline ' z-index: 1;'.
_inline ' background: #fff;'.
_inline ' padding: 0;'.
_inline ' box-shadow: 1px 1px 3px 0px #bbb;'.
_inline '}'.
_inline ''.
_inline '.nav-container ul ul li'.
_inline '{'.
_inline ' float: none;'.
_inline ' min-width: 160px;'.
_inline '}'.
_inline ''.
_inline '.nav-container ul ul a'.
_inline '{'.
_inline ' line-height: 120%;'.
_inline ' padding: 8px 15px;'.
_inline '}'.
_inline ''.
_inline '.nav-container ul ul ul'.
_inline '{'.
_inline ' top: 0;'.
_inline ' left: 100%;'.
_inline '}'.
_inline ''.
_inline '.nav-container.float-right ul ul ul'.
_inline '{'.
_inline ' left: auto;'.
_inline ' right: 100%;'.
_inline '}'.
_inline ''.
_inline '/* Minizone to extent hover area, '.
_inline ' aligned to the left or to the right of the selected item '.
_inline ' depending on .float-right modifier */'.
_inline '.nav-container > ul > li > div.minizone {'.
_inline ' display: none;'.
_inline ' z-index: 1;'.
_inline ' position: absolute;'.
_inline ' padding: 0px;'.
_inline ' width: 16px;'.
_inline ' height: 100%;'.
_inline ' bottom: 0px;'.
_inline ' left: 100%;'.
_inline '}'.
_inline '.nav-container > ul > li:hover div.minizone { display: block; }'.
_inline '.nav-container.float-right > ul > li > div.minizone {'.
_inline ' left: auto;'.
_inline ' right: 100%;'.
_inline '}'.
_inline ''.
_inline '/* icons - text-align strictly left - otherwise look ugly'.
_inline ' + bite a bit of left padding for nicer look '.
_inline ' + forbids item text wrapping (maybe can be done differently) */'.
_inline '.nav-container ul ul li a .octicon {'.
_inline ' padding-right: 10px;'.
_inline ' margin-left: -3px;'.
_inline '}'.
_inline '.nav-container ul.with-icons li {'.
_inline ' text-align: left;'.
_inline ' white-space: nowrap;'.
_inline '}'.
_inline ''.
_inline '/* Special .corner modifier - hangs menu at the top right corner'.
_inline ' and cancels 1st level background coloring */'.
_inline '.nav-container.corner {'.
_inline ' position: absolute;'.
_inline ' right: 0px;'.
_inline '}'.
_inline '.nav-container.corner > ul > li:hover > a { background-color: inherit; }'.
_inline ''.
_inline '/* Toolbar separator style */'.
_inline '.nav-container ul ul li.separator'.
_inline '{'.
_inline ' font-size: x-small;'.
_inline ' text-align: center;'.
_inline ' padding: 4px 0;'.
_inline ' text-transform: uppercase;'.
_inline ' color: #bbb;'.
_inline ' border-bottom: 1px solid #eee;'.
_inline ' border-top: 1px solid #eee;'.
_inline '}'.
_inline '.nav-container ul ul li.separator:first-child { border-top: none; }'.
_inline '.nav-container ul ul li.separator:hover { background-color: inherit; }'.
_inline ''.
_inline '/* News Announcement */'.
_inline ''.
_inline 'div.news { '.
_inline ' position: absolute;'.
_inline ' z-index: 99;'.
_inline ' top: 36px;'.
_inline ' left: 50%;'.
_inline ' width: 40em;'.
_inline ' margin-left: -20em;'.
_inline ' background-color: white;'.
_inline ' box-shadow: 1px 1px 3px 2px #dcdcdc;'.
_inline '}'.
_inline ''.
_inline 'div.news div.headbar {'.
_inline ' text-transform: uppercase;'.
_inline ' font-size: small;'.
_inline ' padding: 4px 6px;'.
_inline '}'.
_inline ''.
_inline 'div.news div.title {'.
_inline ' color: #f8f8f8;'.
_inline ' background-color: #888;'.
_inline '}'.
_inline ''.
_inline 'div.news div.title a.close-btn { '.
_inline ' color: #d8d8d8; '.
_inline ' padding-left: 12px; '.
_inline ' padding-right: 2px;'.
_inline ' position: relative;'.
_inline ' bottom: 1px;'.
_inline '}'.
_inline ''.
_inline 'div.news div.important { color: #aaa; }'.
_inline 'div.news div.newslist {'.
_inline ' padding: 0.5em 0.7em;'.
_inline ' color: #444;'.
_inline '}'.
_inline ''.
_inline 'div.news li {'.
_inline ' padding-left: 10px;'.
_inline ' list-style-type: none;'.
_inline '}'.
_inline ''.
_inline 'div.news h1:first-child { margin: auto; }'.
_inline 'div.news h1 { '.
_inline ' font-size: inherit;'.
_inline ' padding: 6px 4px;'.
_inline ' margin: 4px auto auto;'.
_inline ' text-decoration: underline;'.
_inline ' font-weight: normal;'.
_inline '}'.
_inline ''.
_inline 'div.news .version-marker {'.
_inline ' color: white;'.
_inline ' display: inline-block;'.
_inline ' margin-left: 20px;'.
_inline ' border-radius: 3px;'.
_inline ' padding: 0px 6px;'.
_inline ' border: #c0c0c0 1px solid;'.
_inline ' background-color: #ccc;'.
_inline '}'.
_inline ''.
_inline 'div.news .update {'.
_inline ' border: #e8ba30 1px solid;'.
_inline ' background-color: #f5c538;'.
_inline '}'.
_inline ''.
_inline '.newslist td {'.
_inline ' padding-right: 1em'.
_inline '}'.
_inline ''.
_inline '/* Tooltip text */'.
_inline '.tooltiptext {'.
_inline ' line-height: 15px;'.
_inline ' width: 60px;'.
_inline ' color: #000;'.
_inline ' text-align: center;'.
_inline ' padding: 5px 0;'.
_inline ' border-radius: 6px;'.
_inline ''.
_inline ' /* Position the tooltip text */'.
_inline ' position: absolute;'.
_inline ' z-index: 1;'.
_inline ' margin-left: -60px;'.
_inline ' margin-top: -30px;'.
_inline ''.
_inline ' /* Fade in tooltip */'.
_inline ' opacity: 1;'.
_inline ' transition: opacity 0.3s;'.
_inline '}'.
_inline ''.
_inline '.hidden {'.
_inline ' visibility: hidden;'.
_inline '}'.
_inline ''.
_inline '/* Tooltip arrow */'.
_inline '.tooltiptext::after {'.
_inline ' content: "";'.
_inline ' position: absolute;'.
_inline ' top: 100%;'.
_inline ' left: 50%;'.
_inline ' margin-left: -5px;'.
_inline ' border-width: 5px;'.
_inline ' border-style: solid;'.
_inline ' border-color: #555 transparent transparent transparent;'.
_inline '}'.
WHEN 'JS_COMMON'.
_inline '/**********************************************************'.
_inline ' * ABAPGIT JS function library'.
_inline ' **********************************************************/'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * Polyfills'.
_inline ' **********************************************************/'.
_inline ''.
_inline '// Bind polyfill (for IE7), taken from https://developer.mozilla.org/'.
_inline 'if (!Function.prototype.bind) {'.
_inline ' Function.prototype.bind = function(oThis) {'.
_inline ' if (typeof this !== "function") {'.
_inline ' throw new TypeError("Function.prototype.bind - subject is not callable");'.
_inline ' }'.
_inline ''.
_inline ' var aArgs = Array.prototype.slice.call(arguments, 1),'.
_inline ' fToBind = this,'.
_inline ' fNOP = function() {},'.
_inline ' fBound = function() {'.
_inline ' return fToBind.apply(this instanceof fNOP'.
_inline ' ? this'.
_inline ' : oThis,'.
_inline ' aArgs.concat(Array.prototype.slice.call(arguments)));'.
_inline ' };'.
_inline ''.
_inline ' if (this.prototype) {'.
_inline ' fNOP.prototype = this.prototype; '.
_inline ' }'.
_inline ' fBound.prototype = new fNOP();'.
_inline ''.
_inline ' return fBound;'.
_inline ' };'.
_inline '}'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * Common functions'.
_inline ' **********************************************************/'.
_inline ''.
_inline '// Output text to the debug div'.
_inline 'function debugOutput(text, dstID) {'.
_inline ' var stdout = document.getElementById(dstID || "debug-output");'.
_inline ' var wrapped = "<p>" + text + "</p>";'.
_inline ' stdout.innerHTML = stdout.innerHTML + wrapped;'.
_inline '}'.
_inline ''.
_inline '// Create hidden form and submit with sapevent'.
_inline 'function submitSapeventForm(params, action, method) {'.
_inline ' var form = document.createElement("form");'.
_inline ' form.setAttribute("method", method || "post");'.
_inline ' form.setAttribute("action", "sapevent:" + action);'.
_inline ' '.
_inline ' for(var key in params) {'.
_inline ' var hiddenField = document.createElement("input");'.
_inline ' hiddenField.setAttribute("type", "hidden");'.
_inline ' hiddenField.setAttribute("name", key);'.
_inline ' hiddenField.setAttribute("value", params[key]);'.
_inline ' form.appendChild(hiddenField);'.
_inline ' }'.
_inline ''.
_inline ' document.body.appendChild(form);'.
_inline ' form.submit();'.
_inline '}'.
_inline ''.
_inline '// Set focus to a control'.
_inline 'function setInitialFocus(id) {'.
_inline ' document.getElementById(id).focus();'.
_inline '}'.
_inline ''.
_inline '// Set focus to a element with query selector'.
_inline 'function setInitialFocusWithQuerySelector(sSelector, bFocusParent) {'.
_inline ' var oSelected = document.querySelector(sSelector);'.
_inline ''.
_inline ' if (oSelected) {'.
_inline ' if (bFocusParent) {'.
_inline ' oSelected.parentElement.focus();'.
_inline ' } else {'.
_inline ' oSelected.focus();'.
_inline ' }'.
_inline ' }'.
_inline ''.
_inline '}'.
_inline ''.
_inline '// Submit an existing form'.
_inline 'function submitFormById(id) {'.
_inline ' document.getElementById(id).submit();'.
_inline '}'.
_inline ''.
_inline '// JS error stub'.
_inline 'function errorStub(event) {'.
_inline ' var element = event.target || event.srcElement;'.
_inline ' var targetName = element.id || element.name || "???";'.
_inline ' alert("JS Error, please log an issue (@" + targetName + ")");'.
_inline '}'.
_inline ''.
_inline '// confirm JS initilization'.
_inline 'function confirmInitialized() {'.
_inline ' var errorBanner = document.getElementById("js-error-banner");'.
_inline ' if (errorBanner) {'.
_inline ' errorBanner.style.display = "none";'.
_inline ' }'.
_inline ' debugOutput("js: OK"); // Final final confirmation :)'.
_inline '}'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * Performance utils (for debugging)'.
_inline ' **********************************************************/'.
_inline ''.
_inline 'var gPerf = [];'.
_inline ''.
_inline 'function perfOut(prefix) {'.
_inline ' var totals = {};'.
_inline ' for (var i = gPerf.length - 1; i >= 0; i--) {'.
_inline ' if (!totals[gPerf[i].name]) totals[gPerf[i].name] = {count: 0, time: 0};'.
_inline ' totals[gPerf[i].name].time += gPerf[i].time;'.
_inline ' totals[gPerf[i].name].count += 1;'.
_inline ' }'.
_inline ''.
_inline ' var keys = Object.keys(totals);'.
_inline ' for (var i = keys.length - 1; i >= 0; i--) {'.
_inline ' console.log(prefix '.
_inline ' + " " + keys[i] + ": " '.
_inline ' + totals[keys[i]].time.toFixed(3) + "ms"'.
_inline ' + " (" + totals[keys[i]].count.toFixed() +")");'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline 'function perfLog(name, startTime) {'.
_inline ' gPerf.push({name: name, time: window.performance.now() - startTime});'.
_inline '}'.
_inline ''.
_inline 'function perfClear() {'.
_inline ' gPerf = [];'.
_inline '}'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * TAG PAGE Logic'.
_inline ' **********************************************************/'.
_inline '// somehow only functions on window are visible for the select tag'.
_inline 'window.onTagTypeChange = function(oSelectObject){'.
_inline ' var sValue = oSelectObject.value;'.
_inline ' submitSapeventForm({ ''type'': sValue }, "change_tag_type", "post");'.
_inline '}'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * Repo Overview Logic'.
_inline ' **********************************************************/'.
_inline '// somehow only functions on window are visible for the select tag'.
_inline 'window.onOrderByChange = function(oSelectObject){'.
_inline ' var sValue = oSelectObject.value;'.
_inline ' submitSapeventForm({ ''orderBy'': sValue }, "change_order_by", "post");'.
_inline '}'.
_inline ''.
_inline 'window.onDirectionChange = function(oSelectObject){'.
_inline ' var sValue = oSelectObject.value;'.
_inline ' submitSapeventForm({ ''direction'': sValue }, "direction", "post");'.
_inline '}'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * STAGE PAGE Logic'.
_inline ' **********************************************************/'.
_inline ''.
_inline '// Stage helper constructor'.
_inline 'function StageHelper(params) {'.
_inline ' this.pageSeed = params.seed;'.
_inline ' this.formAction = params.formAction;'.
_inline ' this.choiseCount = 0;'.
_inline ' this.lastSearchValue = "";'.
_inline ''.
_inline ' // DOM nodes'.
_inline ' this.dom = {'.
_inline ' stageTab: document.getElementById(params.ids.stageTab),'.
_inline ' commitBtn: document.getElementById(params.ids.commitBtn),'.
_inline ' commitAllBtn: document.getElementById(params.ids.commitAllBtn),'.
_inline ' objectSearch: document.getElementById(params.ids.objectSearch),'.
_inline ' fileCounter: document.getElementById(params.ids.fileCounter)'.
_inline ' };'.
_inline ' '.
_inline ' // Table columns (autodetection)'.
_inline ' this.colIndex = this.detectColumns();'.
_inline ' this.filterTargets = ["name", "user"];'.
_inline ''.
_inline ' // Constants'.
_inline ' this.HIGHLIGHT_STYLE = "highlight";'.
_inline ' this.STATUS = {'.
_inline ' add: "A",'.
_inline ' remove: "R",'.
_inline ' ignore: "I",'.
_inline ' reset: "?",'.
_inline ' isValid: function (status) { return "ARI?".indexOf(status) == -1; }'.
_inline ' };'.
_inline ' '.
_inline ' this.TEMPLATES = {'.
_inline ' cmdReset: "<a>reset</a>",'.
_inline ' cmdLocal: "<a>add</a>",'.
_inline ' cmdRemote: "<a>ignore</a><a>remove</a>"'.
_inline ' };'.
_inline ''.
_inline ' this.setHooks();'.
_inline '}'.
_inline ''.
_inline '// Hook global click listener on table, load/unload actions'.
_inline 'StageHelper.prototype.setHooks = function() {'.
_inline ' this.dom.stageTab.onclick = this.onTableClick.bind(this);'.
_inline ' this.dom.commitBtn.onclick = this.submit.bind(this);'.
_inline ' this.dom.objectSearch.oninput = this.onSearch.bind(this);'.
_inline ' this.dom.objectSearch.onkeypress = this.onSearch.bind(this);'.
_inline ' window.onbeforeunload = this.onPageUnload.bind(this);'.
_inline ' window.onload = this.onPageLoad.bind(this);'.
_inline '}'.
_inline ''.
_inline '// Detect column index'.
_inline 'StageHelper.prototype.detectColumns = function() {'.
_inline ' var dataRow = this.dom.stageTab.tBodies[0].rows[0];'.
_inline ' var colIndex = {};'.
_inline ''.
_inline ' for (var i = dataRow.cells.length - 1; i >= 0; i--) {'.
_inline ' if (dataRow.cells[i].className) colIndex[dataRow.cells[i].className] = i;'.
_inline ' }'.
_inline ''.
_inline ' return colIndex;'.
_inline '}'.
_inline ''.
_inline '// Store table state on leaving the page'.
_inline 'StageHelper.prototype.onPageUnload = function() {'.
_inline ' if (!window.sessionStorage) return;'.
_inline ''.
_inline ' var data = this.collectData();'.
_inline ' window.sessionStorage.setItem(this.pageSeed, JSON.stringify(data));'.
_inline '}'.
_inline ''.
_inline '// Re-store table state on entering the page'.
_inline 'StageHelper.prototype.onPageLoad = function() {'.
_inline ' var data = window.sessionStorage && JSON.parse(window.sessionStorage.getItem(this.pageSeed));'.
_inline ''.
_inline ' this.iterateStageTab(true, function (row) {'.
_inline ' var status = data && data[row.cells[this.colIndex["name"]].innerText];'.
_inline ' this.updateRow(row, status || this.STATUS.reset);'.
_inline ' });'.
_inline ''.
_inline ' this.updateMenu();'.
_inline ' debugOutput("StageHelper.onPageLoad: " + ((data) ? "from Storage" : "initial state"));'.
_inline '}'.
_inline ''.
_inline '// Table event handler, change status'.
_inline 'StageHelper.prototype.onTableClick = function (event) {'.
_inline ' var target = event.target || event.srcElement;'.
_inline ' if (!target) return;'.
_inline ''.
_inline ' if (target.tagName === "A") {'.
_inline ' var td = target.parentNode;'.
_inline ' } else if (target.tagName === "TD") {'.
_inline ' var td = target;'.
_inline ' if (td.children.length === 1 && td.children[0].tagName === "A") {'.
_inline ' target = td.children[0];'.
_inline ' } else return;'.
_inline ' } else return;'.
_inline ''.
_inline ' if (["TD","TH"].indexOf(td.tagName) == -1 || td.className != "cmd") return;'.
_inline ' '.
_inline ' var status = this.STATUS[target.innerText]; // Convert anchor text to status'.
_inline ' var targetRow = td.parentNode;'.
_inline ' '.
_inline ' if (td.tagName === "TD") {'.
_inline ' this.updateRow(targetRow, status);'.
_inline ' } else { // TH'.
_inline ' this.iterateStageTab(true, function (row) {'.
_inline ' if (row.style.display !== "none" // Not filtered out'.
_inline ' && row.className === targetRow.className // Same context as header'.
_inline ' ) {'.
_inline ' this.updateRow(row, status);'.
_inline ' }'.
_inline ' });'.
_inline ' }'.
_inline ''.
_inline ' this.updateMenu();'.
_inline '}'.
_inline ''.
_inline '// Search object'.
_inline 'StageHelper.prototype.onSearch = function (e) {'.
_inline ' if ( // Enter hit or clear, IE SUCKS !'.
_inline ' e.type === "input" && !e.target.value && this.lastSearchValue'.
_inline ' || e.type === "keypress" && e.which === 13 ) { '.
_inline ''.
_inline ' this.lastSearchValue = e.target.value;'.
_inline ' this.iterateStageTab(true, this.applyFilterToRow, e.target.value);'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline '// Apply filter to a single stage line - hide or show'.
_inline 'StageHelper.prototype.applyFilterToRow = function (row, filter) {'.
_inline ' // Collect data cells'.
_inline ' var targets = this.filterTargets.map(function(attr) {'.
_inline ' var elem = row.cells[this.colIndex[attr]];'.
_inline ' if (elem.firstChild && elem.firstChild.tagName === "A") elem = elem.firstChild;'.
_inline ' return {'.
_inline ' elem: elem,'.
_inline ' plainText: elem.innerText, // without tags'.
_inline ' curHtml: elem.innerHTML'.
_inline ' };'.
_inline ' }, this);'.
_inline ''.
_inline ' var isVisible = false; '.
_inline ''.
_inline ' // Apply filter to cells, mark filtered text'.
_inline ' for (var i = targets.length - 1; i >= 0; i--) {'.
_inline ' var target = targets[i];'.
_inline ' target.newHtml = (filter)'.
_inline ' ? target.plainText.replace(filter, "<mark>"+filter+"</mark>")'.
_inline ' : target.plainText;'.
_inline ' target.isChanged = target.newHtml !== target.curHtml;'.
_inline ' isVisible = isVisible || !filter || target.newHtml !== target.plainText;'.
_inline ' }'.
_inline ''.
_inline ' // Update DOM'.
_inline ' row.style.display = isVisible ? "" : "none";'.
_inline ' for (var i = targets.length - 1; i >= 0; i--) {'.
_inline ' if (targets[i].isChanged) targets[i].elem.innerHTML = targets[i].newHtml;'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline '// Get how status should affect object counter'.
_inline 'StageHelper.prototype.getStatusImpact = function (status) {'.
_inline ' if (typeof status !== "string" '.
_inline ' || status.length !== 1 '.
_inline ' || this.STATUS.isValid(status) ) {'.
_inline ' alert("Unknown status");'.
_inline ' } else {'.
_inline ' return (status !== this.STATUS.reset) ? 1 : 0;'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline '// Update table line'.
_inline 'StageHelper.prototype.updateRow = function (row, newStatus) {'.
_inline ' var oldStatus = row.cells[this.colIndex["status"]].innerText;'.
_inline ''.
_inline ' if (oldStatus !== newStatus) {'.
_inline ' this.updateRowStatus(row, newStatus);'.
_inline ' this.updateRowCommand(row, newStatus);'.
_inline ' } else if (!row.cells[this.colIndex["cmd"]].children.length) {'.
_inline ' this.updateRowCommand(row, newStatus); // For initial run'.
_inline ' }'.
_inline ''.
_inline ' this.choiseCount += this.getStatusImpact(newStatus) - this.getStatusImpact(oldStatus);'.
_inline '}'.
_inline ''.
_inline '// Update Status cell (render set of commands)'.
_inline 'StageHelper.prototype.updateRowStatus = function (row, status) {'.
_inline ' row.cells[this.colIndex["status"]].innerText = status;'.
_inline ' if (status === this.STATUS.reset) {'.
_inline ' row.cells[this.colIndex["status"]].classList.remove(this.HIGHLIGHT_STYLE);'.
_inline ' } else {'.
_inline ' row.cells[this.colIndex["status"]].classList.add(this.HIGHLIGHT_STYLE);'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline '// Update Command cell (render set of commands)'.
_inline 'StageHelper.prototype.updateRowCommand = function (row, status) {'.
_inline ' var cell = row.cells[this.colIndex["cmd"]];'.
_inline ' if (status === this.STATUS.reset) {'.
_inline ' cell.innerHTML = (row.className == "local") '.
_inline ' ? this.TEMPLATES.cmdLocal '.
_inline ' : this.TEMPLATES.cmdRemote;'.
_inline ' } else {'.
_inline ' cell.innerHTML = this.TEMPLATES.cmdReset;'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline '// Update menu items visibility'.
_inline 'StageHelper.prototype.updateMenu = function () {'.
_inline ' this.dom.commitBtn.style.display = (this.choiseCount > 0) ? "" : "none";'.
_inline ' this.dom.commitAllBtn.style.display = (this.choiseCount > 0) ? "none" : "";'.
_inline ' this.dom.fileCounter.innerHTML = this.choiseCount.toString();'.
_inline '}'.
_inline ''.
_inline '// Submit stage state to the server'.
_inline 'StageHelper.prototype.submit = function () {'.
_inline ' submitSapeventForm(this.collectData(), this.formAction);'.
_inline '}'.
_inline ''.
_inline '// Extract data from the table'.
_inline 'StageHelper.prototype.collectData = function () {'.
_inline ' var data = {};'.
_inline ' this.iterateStageTab(false, function (row) {'.
_inline ' data[row.cells[this.colIndex["name"]].innerText] = row.cells[this.colIndex["status"]].innerText;'.
_inline ' });'.
_inline ' return data;'.
_inline '}'.
_inline ''.
_inline '// Table iteration helper'.
_inline 'StageHelper.prototype.iterateStageTab = function (changeMode, cb /*, ...*/) { '.
_inline ' var restArgs = Array.prototype.slice.call(arguments, 2);'.
_inline ' var table = this.dom.stageTab;'.
_inline ''.
_inline ' if (changeMode) {'.
_inline ' var scrollOffset = window.pageYOffset;'.
_inline ' this.dom.stageTab.style.display = "none";'.
_inline ' }'.
_inline ''.
_inline ' for (var b = 0, bN = table.tBodies.length; b < bN; b++) {'.
_inline ' var tbody = table.tBodies[b];'.
_inline ' for (var r = 0, rN = tbody.rows.length; r < rN; r++) {'.
_inline ' args = [tbody.rows[r]].concat(restArgs);'.
_inline ' cb.apply(this, args); // callback'.
_inline ' }'.
_inline ' }'.
_inline ''.
_inline ' if (changeMode) {'.
_inline ' this.dom.stageTab.style.display = "";'.
_inline ' window.scrollTo(0, scrollOffset);'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * Check list wrapper'.
_inline ' **********************************************************/'.
_inline ''.
_inline 'function CheckListWrapper(id, cbAction) {'.
_inline ' this.id = document.getElementById(id);'.
_inline ' this.cbAction = cbAction;'.
_inline ' this.id.onclick = this.onClick.bind(this);'.
_inline '}'.
_inline ''.
_inline 'CheckListWrapper.prototype.onClick = function(e) {'.
_inline ' // Get nodes'.
_inline ' var target = event.target || event.srcElement;'.
_inline ' if (!target) return;'.
_inline ' if (target.tagName !== "A") { target = target.parentNode; } // icon clicked'.
_inline ' if (target.tagName !== "A") return;'.
_inline ' if (target.parentNode.tagName !== "LI") return;'.
_inline ''.
_inline ' var nodeA = target;'.
_inline ' var nodeLi = target.parentNode;'.
_inline ' var nodeIcon = target.children[0];'.
_inline ' if (!nodeIcon.classList.contains("octicon")) return;'.
_inline ''.
_inline ' // Node updates'.
_inline ' var option = nodeA.innerText;'.
_inline ' var oldState = nodeLi.getAttribute("data-check");'.
_inline ' if (oldState === null) return; // no data-check attribute - non-checkbox'.
_inline ' var newState = oldState === "X" ? false : true;'.
_inline ''.
_inline ' if (newState) {'.
_inline ' nodeIcon.classList.remove("grey");'.
_inline ' nodeIcon.classList.add("blue");'.
_inline ' nodeLi.setAttribute("data-check", "X");'.
_inline ' } else {'.
_inline ' nodeIcon.classList.remove("blue");'.
_inline ' nodeIcon.classList.add("grey");'.
_inline ' nodeLi.setAttribute("data-check", "");'.
_inline ' }'.
_inline ''.
_inline ' // Action callback'.
_inline ' this.cbAction(nodeLi.getAttribute("data-aux"), option, newState);'.
_inline '}'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * Diff page logic'.
_inline ' **********************************************************/'.
_inline ''.
_inline '// Diff helper constructor'.
_inline 'function DiffHelper(params) {'.
_inline ' this.pageSeed = params.seed;'.
_inline ' this.counter = 0;'.
_inline ' this.stageAction = params.stageAction;'.
_inline ''.
_inline ' // DOM nodes'.
_inline ' this.dom = {'.
_inline ' diffList: document.getElementById(params.ids.diffList),'.
_inline ' stageButton: document.getElementById(params.ids.stageButton)'.
_inline ' };'.
_inline ''.
_inline ' this.repoKey = this.dom.diffList.getAttribute("data-repo-key");'.
_inline ' if (!this.repoKey) return; // Unexpected'.
_inline ''.
_inline ' // Checklist wrapper'.
_inline ' if (document.getElementById(params.ids.filterMenu)) {'.
_inline ' this.checkList = new CheckListWrapper(params.ids.filterMenu, this.onFilter.bind(this));'.
_inline ' this.dom.filterButton = document.getElementById(params.ids.filterMenu).parentNode;'.
_inline ' } '.
_inline ''.
_inline ' // Hijack stage command'.
_inline ' if (this.dom.stageButton) {'.
_inline ' this.dom.stageButton.href = "#";'.
_inline ' this.dom.stageButton.onclick = this.onStage.bind(this);'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline '// Action on filter click'.
_inline 'DiffHelper.prototype.onFilter = function(attr, target, state) {'.
_inline ' this.applyFilter(attr, target, state);'.
_inline ' this.highlightButton(state);'.
_inline '};'.
_inline ''.
_inline '// Hide/show diff based on params'.
_inline 'DiffHelper.prototype.applyFilter = function (attr, target, state) {'.
_inline ' this.iterateDiffList(function(div) {'.
_inline ' if (div.getAttribute("data-"+attr) === target) {'.
_inline ' div.style.display = state ? "" : "none";'.
_inline ' }'.
_inline ' });'.
_inline '}'.
_inline ''.
_inline '// Action on stage -> save visible diffs as state for stage page'.
_inline 'DiffHelper.prototype.onStage = function (e) {'.
_inline ' if (window.sessionStorage) {'.
_inline ' var data = this.buildStageCache();'.
_inline ' window.sessionStorage.setItem(this.pageSeed, JSON.stringify(data));'.
_inline ' }'.
_inline ' var getParams = {key: this.repoKey, seed: this.pageSeed};'.
_inline ' submitSapeventForm(getParams, this.stageAction, "get");'.
_inline '}'.
_inline ''.
_inline '// Collect visible diffs'.
_inline 'DiffHelper.prototype.buildStageCache = function () {'.
_inline ' var list = {};'.
_inline ' this.iterateDiffList(function(div) {'.
_inline ' var filename = div.getAttribute("data-file");'.
_inline ' if (!div.style.display && filename) { // No display override - visible !!'.
_inline ' list[filename] = "A"; // Add'.
_inline ' }'.
_inline ' });'.
_inline ' return list;'.
_inline '}'.
_inline ''.
_inline '// Table iterator'.
_inline 'DiffHelper.prototype.iterateDiffList = function (cb /*, ...*/) {'.
_inline ' var restArgs = Array.prototype.slice.call(arguments, 1);'.
_inline ' var diffList = this.dom.diffList;'.
_inline ''.
_inline ' for (var i = 0, iN = diffList.children.length; i < iN; i++) {'.
_inline ' var div = diffList.children[i];'.
_inline ' if (div.className !== "diff") continue;'.
_inline ' args = [div].concat(restArgs);'.
_inline ' cb.apply(this, args); // callback'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline '// Highlight Filter button if filter is activate'.
_inline 'DiffHelper.prototype.highlightButton = function(state) {'.
_inline ' this.counter += state ? -1 : 1;'.
_inline ' if (this.counter > 0) {'.
_inline ' this.dom.filterButton.classList.add("bgorange");'.
_inline ' } else {'.
_inline ' this.dom.filterButton.classList.remove("bgorange");'.
_inline ' }'.
_inline '};'.
_inline ''.
_inline '/**********************************************************'.
_inline ' * Other functions'.
_inline ' **********************************************************/'.
_inline ''.
_inline '// News announcement'.
_inline 'function displayNews() {'.
_inline ' var div = document.getElementById("news");'.
_inline ' div.style.display = (div.style.display) ? '''' : ''none'';'.
_inline '}'.
_inline ''.
_inline '// Hotkey Overview '.
_inline 'function closeHotkeyOverview() {'.
_inline ' var div = document.getElementById("hotkeys");'.
_inline ' div.style.display = (div.style.display) ? '''' : ''none'';'.
_inline '}'.
_inline ''.
_inline 'function KeyNavigation() {'.
_inline ' '.
_inline '}'.
_inline ''.
_inline 'KeyNavigation.prototype.onkeydown = function(oEvent) {'.
_inline ''.
_inline ' if (oEvent.defaultPrevented) {'.
_inline ' return;'.
_inline ' }'.
_inline ''.
_inline ' // navigate with arrows through list items and support pressing links with enter and space'.
_inline ' if (oEvent.key === "ENTER" || oEvent.key === "") {'.
_inline ' this.onEnterOrSpace(oEvent);'.
_inline ' } else if (/Down$/.test(oEvent.key)) {'.
_inline ' this.onArrowDown(oEvent);'.
_inline ' } else if (/Up$/.test(oEvent.key)) {'.
_inline ' this.onArrowUp(oEvent);'.
_inline ' }'.
_inline ''.
_inline '};'.
_inline ''.
_inline 'KeyNavigation.prototype.getLiSelected = function() {'.
_inline ' return document.querySelector(''li .selected'');'.
_inline '};'.
_inline ''.
_inline 'KeyNavigation.prototype.getActiveElement = function () {'.
_inline ' return document.activeElement;'.
_inline '};'.
_inline ''.
_inline 'KeyNavigation.prototype.getActiveElementParent = function () {'.
_inline ' return this.getActiveElement().parentElement;'.
_inline '};'.
_inline ''.
_inline 'KeyNavigation.prototype.onEnterOrSpace = function (oEvent) {'.
_inline ' '.
_inline ' // Enter or space clicks the selected link'.
_inline ''.
_inline ' var liSelected = this.getLiSelected();'.
_inline ''.
_inline ' if (liSelected) {'.
_inline ' liSelected.firstElementChild.click();'.
_inline ' }'.
_inline ''.
_inline '};'.
_inline ''.
_inline ''.
_inline 'KeyNavigation.prototype.onArrowDown = function (oEvent) {'.
_inline ''.
_inline ' var'.
_inline ' liNext,'.
_inline ' liSelected = this.getLiSelected(),'.
_inline ' oActiveElementParent = this.getActiveElementParent();'.
_inline ''.
_inline ' if (liSelected) {'.
_inline ''.
_inline ' // we deselect the current li and select the next sibling'.
_inline ' liNext = oActiveElementParent.nextElementSibling;'.
_inline ' if (liNext) {'.
_inline ' liSelected.classList.toggle(''selected'');'.
_inline ' liNext.firstElementChild.focus();'.
_inline ' oActiveElementParent.classList.toggle(''selected'');'.
_inline ' oEvent.preventDefault();'.
_inline ' }'.
_inline ''.
_inline ' } else {'.
_inline ''.
_inline ' // we don''t have any li selected, we have lookup where to start...'.
_inline ' // the right element should have been activated in fnTooltipActivate'.
_inline ' liNext = this.getActiveElement().nextElementSibling;'.
_inline ' if (liNext) {'.
_inline ' liNext.classList.toggle(''selected'');'.
_inline ' liNext.firstElementChild.firstElementChild.focus();'.
_inline ' oEvent.preventDefault();'.
_inline ' }'.
_inline ''.
_inline ' }'.
_inline ''.
_inline '};'.
_inline ''.
_inline ''.
_inline 'KeyNavigation.prototype.onArrowUp = function (oEvent) {'.
_inline ''.
_inline ' var'.
_inline ' liSelected = this.getLiSelected(),'.
_inline ' liPrevious = this.getActiveElementParent().previousElementSibling;'.
_inline ''.
_inline ' if (liSelected && liPrevious) {'.
_inline ''.
_inline ' liSelected.classList.toggle(''selected'');'.
_inline ' liPrevious.firstElementChild.focus();'.
_inline ' this.getActiveElementParent().classList.toggle(''selected'');'.
_inline ' oEvent.preventDefault();'.
_inline ''.
_inline ' }'.
_inline ''.
_inline '};'.
_inline ''.
_inline '// this functions enables the navigation with arrows through list items (li)'.
_inline '// e.g. in dropdown menus'.
_inline 'function enableArrowListNavigation() {'.
_inline ''.
_inline ' var oKeyNavigation = new KeyNavigation();'.
_inline ''.
_inline ' document.addEventListener(''keydown'', oKeyNavigation.onkeydown.bind(oKeyNavigation));'.
_inline ''.
_inline '};'.
_inline ''.
_inline 'function LinkHints(sLinkHintKey, sColor){'.
_inline ' this.sLinkHintKey = sLinkHintKey; '.
_inline ' this.sColor = sColor;'.
_inline ' this.oTooltipMap = {};'.
_inline ' this.bTooltipsOn = false;'.
_inline ' this.sPending = "";'.
_inline ' this.aTooltipElements = document.querySelectorAll(''a span'');'.
_inline '}'.
_inline ''.
_inline 'LinkHints.prototype.fnRenderTooltip = function (oTooltip, iTooltipCounter) {'.
_inline ' if (this.bTooltipsOn) {'.
_inline ' oTooltip.classList.remove(''hidden'');'.
_inline ' } else {'.
_inline ' oTooltip.classList.add(''hidden'');'.
_inline ' }'.
_inline ' oTooltip.innerHTML = iTooltipCounter;'.
_inline ' oTooltip.style.backgroundColor = this.sColor;'.
_inline ' this.oTooltipMap[iTooltipCounter] = oTooltip;'.
_inline '};'.
_inline ''.
_inline 'LinkHints.prototype.getTooltipStartValue = function(iToolTipCount){'.
_inline ' '.
_inline ' // if whe have 333 tooltips we start from 100'.
_inline ' return Math.pow(10,iToolTipCount.toString().length - 1);'.
_inline ''.
_inline '};'.
_inline ''.
_inline 'LinkHints.prototype.fnRenderTooltips = function () {'.
_inline ''.
_inline ' // all possible links which should be accessed via tooltip have'.
_inline ' // sub span which is hidden by default. If we like to show the '.
_inline ' // tooltip we have to toggle the css class ''hidden''.'.
_inline ' // '.
_inline ' // We use numeric values for the tooltip label. Maybe we can '.
_inline ' // support also alphanumeric chars in the future. Then we have to'.
_inline ' // calculate permutations and that''s work. So for the sake of simplicity'.
_inline ' // we stick to numeric values and just increment them.'.
_inline ''.
_inline ' var'.
_inline ' iTooltipCounter = this.getTooltipStartValue(this.aTooltipElements.length),'.
_inline ' that = this;'.
_inline ''.
_inline ' [].forEach.call(this.aTooltipElements, function(oTooltip){'.
_inline ' iTooltipCounter += 1;'.
_inline ' this.fnRenderTooltip(oTooltip, iTooltipCounter)'.
_inline ' }.bind(that));'.
_inline ''.
_inline '};'.
_inline ''.
_inline 'LinkHints.prototype.fnToggleAllTooltips = function () {'.
_inline ''.
_inline ' this.sPending = "";'.
_inline ' this.bTooltipsOn = !this.bTooltipsOn;'.
_inline ' this.fnRenderTooltips();'.
_inline ''.
_inline '};'.
_inline ''.
_inline 'LinkHints.prototype.fnRemoveAllTooltips = function () {'.
_inline ''.
_inline ' this.sPending = "";'.
_inline ' this.bTooltipsOn = false;'.
_inline ''.
_inline ' [].forEach.call(this.aTooltipElements, function (oTooltip) {'.
_inline ' oTooltip.classList.add(''hidden'');'.
_inline ' });'.
_inline ''.
_inline '};'.
_inline ''.
_inline 'LinkHints.prototype.fnFilterTooltips = function (sPending) {'.
_inline ''.
_inline ' var that = this;'.
_inline ''.
_inline ' Object'.
_inline ' .keys(this.oTooltipMap)'.
_inline ' .forEach(function (sKey) {'.
_inline ''.
_inline ' // we try to partially match, but only from the beginning!'.
_inline ' var regex = new RegExp("^" + this.sPending);'.
_inline ' var oTooltip = this.oTooltipMap[sKey];'.
_inline ''.
_inline ' if (regex.test(sKey)) {'.
_inline ' // we have a partial match, grey out the matched part'.
_inline ' oTooltip.innerHTML = sKey.replace(regex, "<div style=''display:inline;color:lightgray''>" + this.sPending + ''</div>'');'.
_inline ' } else {'.
_inline ' // and hide the not matched tooltips'.
_inline ' oTooltip.classList.add(''hidden'');'.
_inline ' }'.
_inline ''.
_inline ' }.bind(that));'.
_inline ''.
_inline '};'.
_inline ''.
_inline 'LinkHints.prototype.fnActivateDropDownMenu = function (oTooltip) {'.
_inline ' // to enable link hint navigation for drop down menu, we must expand '.
_inline ' // like if they were hovered'.
_inline ' oTooltip.parentElement.parentElement.classList.toggle("block");'.
_inline '};'.
_inline ''.
_inline ''.
_inline 'LinkHints.prototype.fnTooltipActivate = function (oTooltip) {'.
_inline ''.
_inline ' // a tooltips was successfully specified, so we try to trigger the link'.
_inline ' // and remove all tooltips'.
_inline ' this.fnRemoveAllTooltips();'.
_inline ' oTooltip.parentElement.click();'.
_inline ''.
_inline ' // in case it is a dropdownmenu we have to expand and focus it'.
_inline ' this.fnActivateDropDownMenu(oTooltip);'.
_inline ' oTooltip.parentElement.focus();'.
_inline ''.
_inline '}'.
_inline ''.
_inline 'LinkHints.prototype.onkeypress = function(oEvent){'.
_inline ''.
_inline ' if (oEvent.defaultPrevented) {'.
_inline ' return;'.
_inline ' }'.
_inline ''.
_inline ' var activeElementType = ((document.activeElement && document.activeElement.nodeName) || "");'.
_inline ' '.
_inline ' // link hints are disabled for input and textareas for obvious reasons.'.
_inline ' // Maybe we must add other types here in the future'.
_inline ' if (oEvent.key === this.sLinkHintKey && activeElementType !== "INPUT" && activeElementType !== "TEXTAREA") {'.
_inline ''.
_inline ' this.fnToggleAllTooltips();'.
_inline ''.
_inline ' } else if (this.bTooltipsOn === true) {'.
_inline ' '.
_inline ' // the user tries to reach a tooltip'.
_inline ' this.sPending += oEvent.key;'.
_inline ' var oTooltip = this.oTooltipMap[this.sPending];'.
_inline ''.
_inline ' if (oTooltip) {'.
_inline ' // we are there, we have a fully specified tooltip. Let''s activate it'.
_inline ' this.fnTooltipActivate(oTooltip);'.
_inline ' } else {'.
_inline ' // we are not there yet, but let''s filter the link so that only'.
_inline ' // the partially matched are shown'.
_inline ' this.fnFilterTooltips(this.sPending);'.
_inline ' }'.
_inline ''.
_inline ' }'.
_inline ''.
_inline '}'.
_inline ''.
_inline '// Vimium like link hints'.
_inline 'function setLinkHints(sLinkHintKey, sColor) {'.
_inline ''.
_inline ' if (!sLinkHintKey || !sColor) {'.
_inline ' return;'.
_inline ' }'.
_inline ''.
_inline ' var oLinkHint = new LinkHints(sLinkHintKey, sColor);'.
_inline ''.
_inline ' document.addEventListener("keypress", oLinkHint.onkeypress.bind(oLinkHint));'.
_inline ''.
_inline '}'.
_inline ''.
_inline 'function Hotkeys(oKeyMap){'.
_inline ''.
_inline ' var that = this; '.
_inline ' this.oKeyMap = oKeyMap || {};'.
_inline ''.
_inline ' // these are the hotkeys provided by the backend'.
_inline ' Object.keys(this.oKeyMap).forEach(function(sKey){'.
_inline ''.
_inline ' var action = that.oKeyMap[sKey]; '.
_inline ' '.
_inline ' // We replace the actions with callback functions to unify'.
_inline ' // the hotkey execution'.
_inline ' that.oKeyMap[sKey] = function(oEvent) {'.
_inline ''.
_inline ' // We have either a js function'.
_inline ' if (that[action]) {'.
_inline ' that[action].call(that);'.
_inline ' return;'.
_inline ' }'.
_inline ' '.
_inline ' // Or a SAP event'.
_inline ' var sUiSapEvent = that.getSapEvent(action);'.
_inline ' if (sUiSapEvent) {'.
_inline ' submitSapeventForm({}, sUiSapEvent, "post");'.
_inline ' oEvent.preventDefault();'.
_inline ' return;'.
_inline ' }'.
_inline ''.
_inline ' }'.
_inline ''.
_inline ' });'.
_inline ''.
_inline '}'.
_inline ''.
_inline 'Hotkeys.prototype.showHotkeys = function() {'.
_inline ' var elHotkeys = document.querySelector(''#hotkeys'');'.
_inline ' '.
_inline ' if (elHotkeys) {'.
_inline ' elHotkeys.style.display = (elHotkeys.style.display) ? '''' : ''none'';'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline 'Hotkeys.prototype.getSapEvent = function(sSapEvent) {'.
_inline ''.
_inline ' var result = "";'.
_inline ' var aSapEvents = document.querySelectorAll(''a[href^="sapevent:'' + sSapEvent + ''"]'');'.
_inline ''.
_inline ' [].forEach.call(aSapEvents, function(sapEvent){'.
_inline ' if (new RegExp(sSapEvent + "$" ).test(sapEvent.href)'.
_inline ' || (new RegExp(sSapEvent + "\\?" ).test(sapEvent.href))) {'.
_inline ' result = sapEvent.href.replace("sapevent:","");'.
_inline ' }'.
_inline ' });'.
_inline ''.
_inline ' return result;'.
_inline ''.
_inline '}'.
_inline ''.
_inline 'Hotkeys.prototype.onkeydown = function(oEvent){'.
_inline ''.
_inline ' if (oEvent.defaultPrevented) {'.
_inline ' return;'.
_inline ' }'.
_inline ''.
_inline ' var activeElementType = ((document.activeElement && document.activeElement.nodeName) || "");'.
_inline ''.
_inline ' if (activeElementType === "INPUT" || activeElementType === "TEXTAREA") {'.
_inline ' return'.
_inline ' }'.
_inline ''.
_inline ' var '.
_inline ' sKey = oEvent.key || oEvent.keyCode,'.
_inline ' fnHotkey = this.oKeyMap[sKey];'.
_inline ''.
_inline ' if (fnHotkey) {'.
_inline ' fnHotkey.call(this, oEvent);'.
_inline ' }'.
_inline '}'.
_inline ''.
_inline 'function setKeyBindings(oKeyMap){'.
_inline ''.
_inline ' var oHotkeys = new Hotkeys(oKeyMap);'.
_inline ''.
_inline ' document.addEventListener(''keydown'', oHotkeys.onkeydown.bind(oHotkeys));'.
_inline ''.
_inline '}'.
WHEN OTHERS.
zcx_abapgit_exception=>raise( |No inline resource: { iv_asset_name }| ).
ENDCASE.
CONCATENATE LINES OF lt_data INTO lv_str SEPARATED BY zif_abapgit_definitions=>c_newline.
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = lv_str
IMPORTING
buffer = rv_data
EXCEPTIONS
OTHERS = 1.
ASSERT sy-subrc = 0.
ENDMETHOD. " get_inline_asset.
METHOD get_inline_images.
DATA ls_image TYPE zif_abapgit_definitions=>ty_web_asset.
ls_image-url = 'img/logo' ##NO_TEXT.
ls_image-base64 =
'iVBORw0KGgoAAAANSUhEUgAAAKMAAAAoCAYAAACSG0qbAAAABHNCSVQICAgIfAhkiAAA'
&& 'AAlwSFlzAAAEJQAABCUBprHeCQAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9y'
&& 'Z5vuPBoAAA8VSURBVHic7Zx7cJzVeYef31nJAtvYko1JjM3FYHlXimwZkLWyLEMcwIGQ'
&& 'cEkDJWmTltLStGkoDCkzwBAuCemUlksDNCkhJTTTljJpZhIuBQxxAWPvyuYiW7UkG8Il'
&& 'UByIsS1sLEu75+0fu5JXu9/etAJz0TOzM/rOec85765+37m+3yczY8w0NU3qrwv9npfa'
&& 'Hfx02pPPd469sgk+7misYnyjpWXy5IOG7kd8ZjjNjEtr13TdOm7eTfCxwo2lUJAQASRu'
&& '2dnRfMn4uDbBx42yxZhPiMNMCHKCsVK2GGuqqqoQUwrZTAhygrFQshjfaGmZ/M7yxQtm'
&& 'xGL9/qDqzwLxQvYTgpygXEoS4/DQ7LE1O05atLBu1YZdE4KcYLwpupoOmCO+5Z2dXPfE'
&& 'xk07Tm2ZroGhBwX1wAygKqiOiVX2Rw9Jam/gyH0wuGGzvTEudRYSY4HFyogghxN2n7Sw'
&& 'IendvcCioLoOtCCXNeqohOf0oDwPq9f3Wt/77dOHlWhYzUj/BRybTnrGEnZO5wv2m0rq'
&& 'DezJoOiqeZbzegzpk6TVPPWJTT39y5svMogF1ZcesjlQgkwYp4F+EJQXwv4E+MiLUZJa'
&& 'F7AIcRq4hWZ2mMRhQD/oZcErXv7FScaja3rt/wpU9E/sFyLACQq57wB/XIl/gWIstn2T'
&& 'xpHVre7ZW71p8sFDeQscSEHKu3pTBadNH2Lq61VT57iwNazLgaNSqYaUaWXLDZCJIbBo'
&& 'g3tK2A2xHns0oMrm3CRrqdTPnAVMiUIEmLlz2XGLMxNmH7YrifFcoUIHalHj8f8p6UfA'
&& 'O+932weStno1zghps6Q7GBFiUYRxopkeaZ2vIwLyfxtQ4vV8lbWHNScacf+T/vwqn90o'
&& 'MZYhRADJ+bv725vmj6Q8tHWffPKUD6IgO/tsfawneRHYd97Pdg8kSyJaZiGtBY4pYPYO'
&& 'kH84C0Cyv8tKSiK7OZ99EpYAJ2V8AhkRY5lCHGaxhaq+BLCzY/EXd5y0aOG0td1vf1AF'
&& 'CWCw7/1u80DQEtahQvcB03MyjQfM7Hwnmxfv9dPivX5SssqOwuzPSqk71mN3ymw5ZtdK'
&& 'dmVIdly8xx7JZ29yy0qptwrGLMRRCA6T1w93nLTo5Lq13Zv625tOMRd6DLF4v0lWmQO8'
&& 'qPko45y7TWaHZyUnwa6M99mN2fYbuu1V4K5oxF1B4Z4UgFifrQHWFLNbvkh1QheV5DNN'
&& 'TZMqFWIGs5zX48M95PTqGa3TZ4erzbvj8/WUErf0L2++uNyGJLn2Js1oDeuYlkbNbmlR'
&& 'deXup2hq0qS2es2VlHMDFaOlRdXL5uuwlnodG23QTEljCkbJV3d7WHOK+dXWqHqZnZeb'
&& 'Y1fGe3OFOArRU5GTGbSHNWdwUL8Epo1qIQ9V/bXu3HES4jCznNfjb7e1zZ8Ri/UD1MLz'
&& 'u05s/huMx4IKGNy4+8Tj/2Pqk8++Vaji86TQqxEuNNM5rWGtSCaokSDkgd0QjbidoPvN'
&& '+5s7t9jz5TgdbdBMvLsG2cop6FgLUdUaZk804jYKuyrWa6vzlT2+XrOqQnxd6KwQOj5R'
&& 'hULpL9Yaxkcj7g3QT6zK397ZbdtGtbtAZ+B0U3adkt0c67E7OyI6fFDuSpktC6HGpJjU'
&& 'GmZ3NOI2mdnVnX32eHZZ7903hGXfBG8mp3J7sd/B0DPCTgUmBf9O7lmMybk56or3Jn8f'
&& 'oLVB7Q5dZ9Iy4OBsw2jYbUUk96fwQrzHf955iBZzsDA+aL9k1owZ20fNzaY/tfFXwK48'
&& 'ldQkSZ5YqJXmZk15JaJfmOmfgdOAmgCzWrCvyum5aIO+Uor3AIbOx7QV2TeBMPu3vKYA'
&& 'Sw091hbWt4PKRhu0oDqkmND1wAnk3vkOmAN2lRLa2hrWMVm5Tek2R3286YzWiK4eQltk'
&& '9g1gMfsFMhVYKunR1obQddk+SXZqwLe8acMGe7fYb9HZk7wm3utrBmpsqiXsyClHMHK6'
&& '0hLWoRjHBfmLbP9K3bPYjFPIFWLaQeZnlZ8H4JyFflrMwcK4wG63v3/ycZnXOzqalxE0'
&& 'mU7x9rvvVv93oVZqBtzNGGeU7Jbp9pZGzS7ReiVQVyDfmXRda4PaA9p5mBLmWGmmSron'
&& 'M0FytUGGgjPTAi8UIeVk9u1og5YOJ0QbNBOjIac+Y22JPgLQ1WV7Ol+w36xebYnhtGpj'
&& 'FjBYTj3l4KY9/dx6My4d74pN/Ki/Y9HpSG5HR/Nyh/1DHtO9OM6dvWFDwbtWslOykt6U'
&& 's5VWZbOFnQtsyMqvc56Ty3T7NeBhLGAfDZDpe5nX6V5uXpbZ43K2NGQ2V9glwLas/I62'
&& 'hfrE8EWsJ3mFsGYs+OQqze+A1cBLgbmma4f/9AmOJGBe5vKVLYN1W6wnOWSHmdkVhexM'
&& 'PG6yC0x2AbmjoQ3njdh4uwrSw1Htmq5bd3Y0I3FLpQ5n0GTSQ7s6Fva70RPYTPbi+Pz0'
&& 'J7ryboRC+m5PnRfsJjVEAfp5bLNflTb52dKIBj36RWY5ZyX2WCLukvbX67ZYHFLHZtGw'
&& '+1fD/jDL8qQljWpav9m6Uw3wKYzXgUNJTxsk+0Fssw0L6x+j4dCx6eF/BEtwDBkbx7Fe'
&& '29gWCa0yrC2rvXXO26WZfrWG3V2kji8zWbm0QUev67GX5ZgZ8A0H121hXIIZNrxou9oW'
&& '6m4b4m/z2aTP+fsAohF3PaNHROvssZ8ElRs5DnyPBAkovxDFF4oJESDeY9tJD4Ur5umg'
&& 'PSFm1Uy23Zk2SaM7e43p5Y4uxUMzu2f4H56+tuZmff2gfTqHrGEy5DkW6Abo7LH7gfsB'
&& '2uo1LQGzBmoYFSwg57vNcjqqo4F1JXh2S7Zfx83TZZNqdD6MXkQkU369jONgcmfxe83M'
&& 'B7XQEdEhg1B0HzDk2ZHpy3vBqLPpMQhyi/f2AIA3WyPZG6KkeVpKiE925awEi7H6JRsA'
&& 'cqJDfIi9oayfW8ZB5dY/TFeX7YlGQg+RmgJkcnSQfWyr9QP92enmGcgeNCvx67mXbGdb'
&& 'xD1hjI5AklJ+ydgTUGz6iiZNXd09+gYGGIRlQgXn6wDesZYSRFsJOYES5QjSw7fqnu7q'
&& 'Bqh7uqu7f3nzdw3uKFJszEIcpqVRs12SRuAYiTrJ1YXMzSGgS6iQnHmWyQWe70pySz/F'
&& 'MZagMWnMlaiTuTqTTih7s7IIHm1T1ncVI37l3BAAA4McAYF7iAvG17uxExi1U6Igd9XN'
&& 'Dj+UmZA8qPrf3MDQbeSPIN8Ldub0JzeWLcT2I3Swn8JFhr4VQnMze5uKnv0ugOHfUXa3'
&& 'ZhySedkR0eGDuMtbw/rTZCI1pA9PF0yWf4e3MnJ7YKXm0pOr6H03QRIIZeYnUj1njhid'
&& '8aaRscKX/VGWSRLsCjnK2rcdC3njGUsQ5PSdv92yqJaMk5WBoRMpJsSnNgZufBdCkmsN'
&& '60FgRbllK8PNzOlttT/qpz2sOUnpeWGHvq9ewcyc28/7XQCru213NOL+l6wgZ0kXAjnD'
&& 'cazP7gXuTdu41rCyxbgr3mt/P16+F6LgUVXtmq5bC237yNsNu5YtPBZgx4kLFznZ1XlM'
&& 'BzB/1liECBAN801yhfiq0HflbKXz1ojZ4qCylSBsbm6q/93wX0n0Q1Ir6UzWYXaZyZaF'
&& 'qqxeZn813n4ZlhPWJWXMo00P5OTDF5c0qmm8fRlPip6bFhHk6Ti3ddfy5i3OXBemJQE2'
&& 'A5g/c/qaTasC8krC0KdzE+3qWG/y6thmW7Vui/UkQ7w51vqDaGnRZFInPdlshNQ2C8oJ'
&& 'h0oqaefF++zmzh5bu7bbXrBxjp88bp5qgZzNdyfWD/9t+B+TO4GW8/p+R0SHcGBxLWEF'
&& 'jiQlHeIXEaRIPZAVRMVCTDcQCUh8LfOyaqjgCcr+YpY7NRFa2VY/egsqtNtdw8ie5gjJ'
&& 'oUTqicjofOYA2f/YgcR03s5MMBF4wlIa7rMr5mnUyru6xl0LZAeFvDG3l83DF5199muk'
&& 'oJO1FUMoviSi8Nh9Kg+Ru7qvUvCqPO+cMZsxbPsM4HXW9KcrEyKApTa7s9BVSyLaF3Ik'
&& 'SbLSQros18RyInkkV2u5q+6zLaS+aCT0oJl/QVI78IWcsvDos1vtLYCE551QKNuCKW63'
&& '+157g36cMOYI9yWhC3K+j4KDEHKxC9+t0altDaFHwL/kvVZIBJw761/uM5/MTJlU7S/Z'
&& 'N6hTBNlhZA0OPReNuGdM6nL4jR4G5ZnRusAtKmVHwg1Slcxe11nODZJKh1fJ6kwM3dQa'
&& 'VgOw3omjkGuL9/o/L/vFTzs7mi8pQZBpIT4f9PxE2bRFQncY9pdjKDoExDH7ebzPbgFo'
&& 'bQjdng48KBfvzZau77ORN61FI66PsW2N7ARiZnZTZ589BtAWCV1v5J1zF+JNVdui2CbL'
&& 'OcJsq1ejD2lVgCDL4e14r58J0N6k+cmEu0HYIssdrbxgnaGeeG9yJEg32hC6GbOix81y'
&& 'trTsWLtiixpgQNLZ4yVEgCT++xSP0H7C0N1ZadVAh6SR3kRm2WfJO0H/XqTuQcn+IlOI'
&& 'AFjRVaZhus3g2az0WuA0wcIi5QP3DDNIIPtakBABYltts7AO4OEi9eTFYGCksSRzwM4L'
&& 'ECKAM1gG9tVR5UP+RkqZN5s7a0yBnwUEOSDp7GlPPp83BH0srO+1PmQrDIIen9wOdnln'
&& 'n31G5n9ZtDLL6ck2x3uTf6DUee8rASX6vNnyWI/dmZ0R77O7LNXLBkWy9CE7Pd6XvNih'
&& 'QkEQeZHZl9PBFtsDstebtyWFwv0B4r32UrzXn+6xDtBdwIslNL0N+JnMvravxiraFO/s'
&& 'tm0y+xzQlcfkddCNCe/vGfP7GQH6lzdfbHAjqSCBHZK+PN5CzESSlixgnhMLzXAeXp+3'
&& 'hWfuM0sWL10abQv1CdtHixzvmtiYPhcvSFOTJk1NEPEQkWdPUry4oc96y2o3YJiWs5Wx'
&& 'zbYq83THHHu9Y1N2kG45tDRqdsgzxxuznKPOGbsTsN2M7d6zfXhePJ5Ici1h6mUcAcw0'
&& '8Zo5fp35NoqKxAjwTrRhZmLSpPY9ySmPzV27dm+lTn9cKSTGA+XT+03Jq+l8HBLv2Q7c'
&& 'X9K+ygQTFGDcHhaaoGJyouDNV7JH+eGj4mF6gspoC+tzJt1ObsT4MDsF2zxs886+Ml5v'
&& '/PogUvEwPUGFiE+SX4gAtQa1gkhV7onQR4oJMR5oxC6stDeghd7Dh6E+CPw/HL4vVO2f'
&& 'cpUAAAAASUVORK5CYII='.
APPEND ls_image TO rt_images.
ENDMETHOD. " get_inline_images.
METHOD get_mime_asset.
DATA: ls_key TYPE wwwdatatab,
lv_size_c TYPE wwwparams-value,
lv_size TYPE i,
lt_w3mime TYPE STANDARD TABLE OF w3mime.
ls_key-relid = 'MI'.
ls_key-objid = iv_asset_name.
" Get exact file size
CALL FUNCTION 'WWWPARAMS_READ'
EXPORTING
relid = ls_key-relid
objid = ls_key-objid
name = 'filesize'
IMPORTING
value = lv_size_c
EXCEPTIONS
entry_not_exists = 1.
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
lv_size = lv_size_c.
" Get binary data
CALL FUNCTION 'WWWDATA_IMPORT'
EXPORTING
key = ls_key
TABLES
mime = lt_w3mime
EXCEPTIONS
wrong_object_type = 1
import_error = 2.
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
EXPORTING
input_length = lv_size
IMPORTING
buffer = rv_data
TABLES
binary_tab = lt_w3mime
EXCEPTIONS
failed = 1 ##FM_SUBRC_OK.
ENDMETHOD. " get_mime_asset.
METHOD get_webfont_link.
rv_link = '<link rel="stylesheet"'
&& ' type="text/css" href="'
&& 'https://cdnjs.cloudflare.com/ajax/libs/octicons/4.4.0/font/octicons.min.css'
&& '">'. "#EC NOTEXT
ENDMETHOD. " get_webfont_link
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI IMPLEMENTATION.
METHOD back.
DATA: lv_index TYPE i,
ls_stack LIKE LINE OF mt_stack.
lv_index = lines( mt_stack ).
IF lv_index = 0.
rv_exit = abap_true.
RETURN.
ENDIF.
DO lv_index TIMES.
READ TABLE mt_stack INDEX lv_index INTO ls_stack.
ASSERT sy-subrc = 0.
DELETE mt_stack INDEX lv_index.
ASSERT sy-subrc = 0.
lv_index = lv_index - 1.
IF iv_to_bookmark = abap_false OR ls_stack-bookmark = abap_true.
EXIT.
ENDIF.
ENDDO.
mi_cur_page = ls_stack-page. " last page always stays
render( ).
ENDMETHOD. "back
METHOD cache_asset.
DATA: lv_xstr TYPE xstring,
lt_xdata TYPE TABLE OF w3_mime, " RAW255
lv_size TYPE int4.
ASSERT iv_text IS SUPPLIED OR iv_xdata IS SUPPLIED.
IF iv_text IS SUPPLIED. " String input
CALL FUNCTION 'SCMS_STRING_TO_XSTRING'
EXPORTING
text = iv_text
IMPORTING
buffer = lv_xstr
EXCEPTIONS
OTHERS = 1.
ASSERT sy-subrc = 0.
ELSE. " Raw input
lv_xstr = iv_xdata.
ENDIF.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xstr
IMPORTING
output_length = lv_size
TABLES
binary_tab = lt_xdata.
mo_html_viewer->load_data(
EXPORTING
type = iv_type
subtype = iv_subtype
size = lv_size
url = iv_url
IMPORTING
assigned_url = rv_url
CHANGING
data_table = lt_xdata
EXCEPTIONS
OTHERS = 1 ) ##NO_TEXT.
ASSERT sy-subrc = 0. " Image data error
ENDMETHOD. " cache_asset.
METHOD cache_html.
rv_url = cache_asset( iv_text = iv_text
iv_type = 'text'
iv_subtype = 'html' ).
ENDMETHOD. "cache_html
METHOD call_page.
DATA: ls_stack TYPE ty_page_stack.
IF iv_replacing = abap_false AND NOT mi_cur_page IS INITIAL.
ls_stack-page = mi_cur_page.
ls_stack-bookmark = iv_with_bookmark.
APPEND ls_stack TO mt_stack.
ENDIF.
mi_cur_page = ii_page.
render( ).
ENDMETHOD. "call_page
METHOD constructor.
startup( ).
ENDMETHOD. "constructor
METHOD focus.
cl_gui_control=>set_focus( mo_html_viewer ).
ENDMETHOD.
METHOD get_current_page_name.
IF mi_cur_page IS BOUND.
rv_page_name =
cl_abap_classdescr=>describe_by_object_ref( mi_cur_page
)->get_relative_name( ).
SHIFT rv_page_name LEFT DELETING LEADING 'LCL_GUI_'.
ENDIF." ELSE - return is empty => initial page
ENDMETHOD. "get_current_page_name
METHOD get_instance.
IF go_gui IS INITIAL.
CREATE OBJECT go_gui.
ENDIF.
ro_gui = go_gui.
ENDMETHOD.
METHOD go_home.
on_event( action = |{ zif_abapgit_definitions=>c_action-go_main }| ). " doesn't accept strings directly
ENDMETHOD. "go_home
METHOD handle_action.
DATA: lx_exception TYPE REF TO zcx_abapgit_exception,
li_page TYPE REF TO zif_abapgit_gui_page,
lv_state TYPE i.
TRY.
IF mi_cur_page IS BOUND.
mi_cur_page->on_event(
EXPORTING
iv_action = iv_action
iv_prev_page = get_current_page_name( )
iv_getdata = iv_getdata
it_postdata = it_postdata
IMPORTING
ei_page = li_page
ev_state = lv_state ).
ENDIF.
IF lv_state IS INITIAL.
mo_router->on_event(
EXPORTING
iv_action = iv_action
iv_prev_page = get_current_page_name( )
iv_getdata = iv_getdata
it_postdata = it_postdata
IMPORTING
ei_page = li_page
ev_state = lv_state ).
ENDIF.
CASE lv_state.
WHEN zif_abapgit_definitions=>c_event_state-re_render.
render( ).
WHEN zif_abapgit_definitions=>c_event_state-new_page.
call_page( li_page ).
WHEN zif_abapgit_definitions=>c_event_state-new_page_w_bookmark.
call_page( ii_page = li_page iv_with_bookmark = abap_true ).
WHEN zif_abapgit_definitions=>c_event_state-new_page_replacing.
call_page( ii_page = li_page iv_replacing = abap_true ).
WHEN zif_abapgit_definitions=>c_event_state-go_back.
back( ).
WHEN zif_abapgit_definitions=>c_event_state-go_back_to_bookmark.
back( abap_true ).
WHEN zif_abapgit_definitions=>c_event_state-no_more_act.
" Do nothing, handling completed
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Unknown action: { iv_action }| ).
ENDCASE.
CATCH zcx_abapgit_exception INTO lx_exception.
ROLLBACK WORK.
MESSAGE lx_exception TYPE 'S' DISPLAY LIKE 'E'.
CATCH zcx_abapgit_cancel ##NO_HANDLER.
" Do nothing = gc_event_state-no_more_act
ENDTRY.
ENDMETHOD. "handle_action
METHOD on_event.
handle_action(
iv_action = action
iv_frame = frame
iv_getdata = getdata
it_postdata = postdata
it_query_table = query_table ).
ENDMETHOD. "on_event
METHOD render.
DATA: lv_url TYPE w3url,
lo_html TYPE REF TO zcl_abapgit_html.
lo_html = mi_cur_page->render( ).
lv_url = cache_html( lo_html->render( iv_no_indent_jscss = abap_true ) ).
mo_html_viewer->show_url( lv_url ).
ENDMETHOD. "render
METHOD startup.
DATA: lt_events TYPE cntl_simple_events,
ls_event LIKE LINE OF lt_events,
lt_assets TYPE zif_abapgit_definitions=>tt_web_assets.
FIELD-SYMBOLS <ls_asset> LIKE LINE OF lt_assets.
CREATE OBJECT mo_router.
CREATE OBJECT mo_asset_man.
CREATE OBJECT mo_html_viewer
EXPORTING
query_table_disabled = abap_true
parent = cl_gui_container=>screen0.
cache_asset( iv_xdata = mo_asset_man->get_asset( 'css_common' )
iv_url = 'css/common.css'
iv_type = 'text'
iv_subtype = 'css' ).
cache_asset( iv_xdata = mo_asset_man->get_asset( 'js_common' )
iv_url = 'js/common.js'
iv_type = 'text'
iv_subtype = 'javascript' ).
lt_assets = mo_asset_man->get_images( ).
IF lines( lt_assets ) > 0.
LOOP AT lt_assets ASSIGNING <ls_asset>.
cache_asset( iv_xdata = <ls_asset>-content
iv_url = <ls_asset>-url
iv_type = 'image'
iv_subtype = 'png' ).
ENDLOOP.
ENDIF.
ls_event-eventid = mo_html_viewer->m_id_sapevent.
ls_event-appl_event = abap_true.
APPEND ls_event TO lt_events.
mo_html_viewer->set_registered_events( lt_events ).
SET HANDLER me->on_event FOR mo_html_viewer.
ENDMETHOD. "startup
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_DB_EDIT IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
ms_key = is_key.
ms_control-page_title = 'CONFIG EDIT'.
ENDMETHOD.
METHOD dbcontent_decode.
DATA: lt_fields TYPE tihttpnvp,
lv_string TYPE string.
CONCATENATE LINES OF it_postdata INTO lv_string.
lv_string = cl_http_utility=>unescape_url( lv_string ).
rs_content = zcl_abapgit_html_action_utils=>dbkey_decode( lv_string ).
lt_fields = zcl_abapgit_html_action_utils=>parse_fields_upper_case_name( lv_string ).
zcl_abapgit_html_action_utils=>get_field(
EXPORTING
iv_name = 'XMLDATA'
it_field = lt_fields
CHANGING
cg_field = rs_content-data_str ).
IF rs_content-data_str(1) <> '<' AND rs_content-data_str+1(1) = '<'. " Hmmm ???
rs_content-data_str = rs_content-data_str+1.
ENDIF.
ENDMETHOD.
METHOD render_content.
DATA: lv_data TYPE zif_abapgit_persistence=>ty_content-data_str,
lo_toolbar TYPE REF TO zcl_abapgit_html_toolbar.
TRY.
lv_data = zcl_abapgit_persistence_db=>get_instance( )->read(
iv_type = ms_key-type
iv_value = ms_key-value ).
CATCH zcx_abapgit_not_found ##NO_HANDLER.
ENDTRY.
zcl_abapgit_persistence_db=>get_instance( )->lock(
iv_type = ms_key-type
iv_value = ms_key-value ).
lv_data = escape( val = zcl_abapgit_xml_pretty=>print( lv_data )
format = cl_abap_format=>e_html_attr ).
CREATE OBJECT ro_html.
CREATE OBJECT lo_toolbar.
lo_toolbar->add( iv_act = 'submitFormById(''db_form'');'
iv_txt = 'Save'
iv_typ = zif_abapgit_definitions=>c_action_type-onclick
iv_opt = zif_abapgit_definitions=>c_html_opt-strong ) ##NO_TEXT.
ro_html->add( '<div class="db_entry">' ).
" Banners & Toolbar
ro_html->add( '<table class="toolbar"><tr><td>' ).
ro_html->add( zcl_abapgit_gui_page_db_dis=>render_record_banner( ms_key ) ).
ro_html->add( '</td><td>' ).
ro_html->add( lo_toolbar->render( iv_right = abap_true ) ).
ro_html->add( '</td></tr></table>' ).
" Form
ro_html->add( |<form id="db_form" method="post" action="sapevent:| && |{ c_action-update }">| ).
ro_html->add( |<input type="hidden" name="type" value="{ ms_key-type }">| ).
ro_html->add( |<input type="hidden" name="value" value="{ ms_key-value }">| ).
ro_html->add( |<textarea rows="20" cols="100" name="xmldata">{ lv_data }</textarea>| ).
ro_html->add( '</form>' ).
ro_html->add( '</div>' ). "db_entry
ENDMETHOD.
METHOD update.
ASSERT is_content-type IS NOT INITIAL.
zcl_abapgit_persistence_db=>get_instance( )->update(
iv_type = is_content-type
iv_value = is_content-value
iv_data = is_content-data_str ).
COMMIT WORK.
ENDMETHOD.
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA: ls_db TYPE zif_abapgit_persistence=>ty_content.
CASE iv_action.
WHEN c_action-update.
ls_db = dbcontent_decode( it_postdata ).
update( ls_db ).
ev_state = zif_abapgit_definitions=>c_event_state-go_back.
ENDCASE.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_DB_DIS IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
ms_key = is_key.
ms_control-page_title = 'CONFIG DISPLAY'.
ENDMETHOD.
METHOD render_content.
DATA:
lo_highlighter TYPE REF TO zcl_abapgit_syntax_highlighter,
lo_toolbar TYPE REF TO zcl_abapgit_html_toolbar,
lv_data TYPE zif_abapgit_persistence=>ty_content-data_str,
ls_action TYPE zif_abapgit_persistence=>ty_content,
lv_action TYPE string.
TRY.
lv_data = zcl_abapgit_persistence_db=>get_instance( )->read(
iv_type = ms_key-type
iv_value = ms_key-value ).
CATCH zcx_abapgit_not_found ##NO_HANDLER.
ENDTRY.
" Create syntax highlighter
lo_highlighter = zcl_abapgit_syntax_highlighter=>create( '*.xml' ).
ls_action-type = ms_key-type.
ls_action-value = ms_key-value.
lv_action = zcl_abapgit_html_action_utils=>dbkey_encode( ls_action ).
lv_data = lo_highlighter->process_line( zcl_abapgit_xml_pretty=>print( lv_data ) ).
CREATE OBJECT ro_html.
CREATE OBJECT lo_toolbar.
lo_toolbar->add( iv_act = |{ zif_abapgit_definitions=>c_action-db_edit }?{ lv_action }|
iv_txt = 'Edit' ) ##NO_TEXT.
ro_html->add( '<div class="db_entry">' ).
ro_html->add( '<table class="toolbar"><tr><td>' ).
ro_html->add( render_record_banner( ms_key ) ).
ro_html->add( '</td><td>' ).
ro_html->add( lo_toolbar->render( iv_right = abap_true ) ).
ro_html->add( '</td></tr></table>' ).
ro_html->add( |<pre class="syntax-hl">{ lv_data }</pre>| ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD render_record_banner.
rv_html = |<table class="tag"><tr><td class="label">Type:</td>|
&& | <td>{ is_key-type }</td></tr></table>|
&& zif_abapgit_definitions=>c_newline
&& |<table class="tag"><tr><td class="label">Key:</td>|
&& | <td>{ is_key-value }</td></tr></table>|.
ENDMETHOD. "render_record_banner
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GUI_PAGE_DB IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
ms_control-page_title = 'DATABASE PERSISTENCY'.
ENDMETHOD. " constructor.
METHOD delete.
DATA: lv_answer TYPE c LENGTH 1.
ASSERT is_key-type IS NOT INITIAL.
lv_answer = zcl_abapgit_ui_factory=>get_popups( )->popup_to_confirm(
iv_titlebar = 'Warning'
iv_text_question = 'Delete?'
iv_text_button_1 = 'Ok'
iv_icon_button_1 = 'ICON_DELETE'
iv_text_button_2 = 'Cancel'
iv_icon_button_2 = 'ICON_CANCEL'
iv_default_button = '2'
iv_display_cancel_button = abap_false ). "#EC NOTEXT
IF lv_answer = '2'.
RAISE EXCEPTION TYPE zcx_abapgit_cancel.
ENDIF.
zcl_abapgit_persistence_db=>get_instance( )->delete(
iv_type = is_key-type
iv_value = is_key-value ).
COMMIT WORK.
ENDMETHOD. " delete
METHOD explain_content.
DATA: ls_result TYPE match_result,
ls_match TYPE submatch_result,
lv_cnt TYPE i.
CASE is_data-type.
WHEN 'REPO'.
FIND FIRST OCCURRENCE OF REGEX '<url>(.*)</url>'
IN is_data-data_str IGNORING CASE RESULTS ls_result.
READ TABLE ls_result-submatches INTO ls_match INDEX 1.
IF sy-subrc IS INITIAL.
rv_text = is_data-data_str+ls_match-offset(ls_match-length).
ENDIF.
FIND FIRST OCCURRENCE OF REGEX '<OFFLINE/>'
IN is_data-data_str IGNORING CASE MATCH COUNT lv_cnt.
IF lv_cnt > 0.
rv_text = |<strong>On-line</strong>, Name: <strong>{
zcl_abapgit_url=>name( rv_text ) }</strong>|.
ELSE.
rv_text = |Off-line, Name: <strong>{ rv_text }</strong>|.
ENDIF.
WHEN 'BACKGROUND'.
FIND FIRST OCCURRENCE OF REGEX '<method>(.*)</method>'
IN is_data-data_str IGNORING CASE RESULTS ls_result.
READ TABLE ls_result-submatches INTO ls_match INDEX 1.
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
rv_text = |Method: { is_data-data_str+ls_match-offset(ls_match-length) }, |
&& |Repository: { zcl_abapgit_repo_srv=>get_instance( )->get( is_data-value )->get_name( ) }|.
WHEN 'USER'.
rv_text = '-'. " No additional explanation for user
WHEN 'SETTINGS'.
rv_text = '-'.
WHEN OTHERS.
IF strlen( is_data-data_str ) >= 250.
rv_text = is_data-data_str(250).
ELSE.
rv_text = is_data-data_str.
ENDIF.
rv_text = escape( val = rv_text
format = cl_abap_format=>e_html_attr ).
rv_text = |<pre>{ rv_text }</pre>|.
ENDCASE.
ENDMETHOD. "explain_content
METHOD render_content.
DATA: lt_data TYPE zif_abapgit_persistence=>tt_content,
lv_action TYPE string,
lv_trclass TYPE string,
lo_toolbar TYPE REF TO zcl_abapgit_html_toolbar.
FIELD-SYMBOLS: <ls_data> LIKE LINE OF lt_data.
lt_data = zcl_abapgit_persistence_db=>get_instance( )->list( ).
CREATE OBJECT ro_html.
ro_html->add( '<div class="db_list">' ).
ro_html->add( '<table class="db_tab">' ).
" Header
ro_html->add( '<thead>' ).
ro_html->add( '<tr>' ).
ro_html->add( '<th>Type</th>' ).
ro_html->add( '<th>Key</th>' ).
ro_html->add( '<th>Data</th>' ).
ro_html->add( '<th></th>' ).
ro_html->add( '</tr>' ).
ro_html->add( '</thead>' ).
ro_html->add( '<tbody>' ).
" Lines
LOOP AT lt_data ASSIGNING <ls_data>.
CLEAR lv_trclass.
IF sy-tabix = 1.
lv_trclass = ' class="firstrow"' ##NO_TEXT.
ENDIF.
lv_action = zcl_abapgit_html_action_utils=>dbkey_encode( <ls_data> ).
CREATE OBJECT lo_toolbar.
lo_toolbar->add( iv_txt = 'Display' iv_act = |{ zif_abapgit_definitions=>c_action-db_display }?{ lv_action }| ).
lo_toolbar->add( iv_txt = 'Edit' iv_act = |{ zif_abapgit_definitions=>c_action-db_edit }?{ lv_action }| ).
lo_toolbar->add( iv_txt = 'Delete' iv_act = |{ c_action-delete }?{ lv_action }| ).
ro_html->add( |<tr{ lv_trclass }>| ).
ro_html->add( |<td>{ <ls_data>-type }</td>| ).
ro_html->add( |<td>{ <ls_data>-value }</td>| ).
ro_html->add( |<td class="data">{ explain_content( <ls_data> ) }</td>| ).
ro_html->add( '<td>' ).
ro_html->add( lo_toolbar->render( ) ).
ro_html->add( '</td>' ).
ro_html->add( '</tr>' ).
ENDLOOP.
ro_html->add( '</tbody>' ).
ro_html->add( '</table>' ).
ro_html->add( '</div>' ).
ENDMETHOD. "render_content
METHOD zif_abapgit_gui_page_hotkey~get_hotkey_actions.
ENDMETHOD.
METHOD zif_abapgit_gui_page~on_event.
DATA: ls_db TYPE zif_abapgit_persistence=>ty_content.
CASE iv_action.
WHEN c_action-delete.
ls_db = zcl_abapgit_html_action_utils=>dbkey_decode( iv_getdata ).
delete( ls_db ).
ev_state = zif_abapgit_definitions=>c_event_state-re_render.
ENDCASE.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_TEST_SERIALIZE IMPLEMENTATION.
METHOD check.
DATA: lt_files TYPE zif_abapgit_definitions=>ty_files_tt.
lt_files = zcl_abapgit_objects=>serialize(
is_item = is_item
iv_language = zif_abapgit_definitions=>c_english ).
cl_abap_unit_assert=>assert_not_initial( lt_files ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_syntax_xml IMPLEMENTATION.
METHOD constructor.
super->constructor( ).
" Initialize instances of regular expressions
add_rule( iv_regex = c_regex-xml_tag
iv_token = c_token-xml_tag
iv_style = c_css-xml_tag ).
add_rule( iv_regex = c_regex-attr
iv_token = c_token-attr
iv_style = c_css-attr ).
add_rule( iv_regex = c_regex-attr_val
iv_token = c_token-attr_val
iv_style = c_css-attr_val ).
ENDMETHOD.
METHOD order_matches.
DATA:
lv_index TYPE sy-tabix,
lv_prev_token TYPE c,
lv_state TYPE c VALUE 'O'. " O - for open tag; C - for closed tag;
FIELD-SYMBOLS:
<ls_prev> TYPE ty_match,
<ls_match> TYPE ty_match.
SORT ct_matches BY offset.
LOOP AT ct_matches ASSIGNING <ls_match>.
lv_index = sy-tabix.
CASE <ls_match>-token.
WHEN c_token-xml_tag.
<ls_match>-text_tag = substring( val = iv_line
off = <ls_match>-offset
len = <ls_match>-length ).
" No other matches between two tags
IF <ls_match>-text_tag = '>' AND lv_prev_token = c_token-xml_tag.
lv_state = 'C'.
<ls_prev>-length = <ls_match>-offset - <ls_prev>-offset + <ls_match>-length.
DELETE ct_matches INDEX lv_index.
CONTINUE.
" Adjust length and offset of closing tag
ELSEIF <ls_match>-text_tag = '>' AND lv_prev_token <> c_token-xml_tag.
lv_state = 'C'.
IF <ls_prev> IS ASSIGNED.
<ls_match>-length = <ls_match>-offset - <ls_prev>-offset - <ls_prev>-length + <ls_match>-length.
<ls_match>-offset = <ls_prev>-offset + <ls_prev>-length.
ENDIF.
ELSE.
lv_state = 'O'.
ENDIF.
WHEN OTHERS.
IF lv_prev_token = c_token-xml_tag.
<ls_prev>-length = <ls_match>-offset - <ls_prev>-offset. " Extend length of the opening tag
ENDIF.
IF lv_state = 'C'. " Delete all matches between tags
DELETE ct_matches INDEX lv_index.
CONTINUE.
ENDIF.
ENDCASE.
lv_prev_token = <ls_match>-token.
ASSIGN <ls_match> TO <ls_prev>.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_SYNTAX_HIGHLIGHTER IMPLEMENTATION.
METHOD add_rule.
DATA ls_rule LIKE LINE OF mt_rules.
CREATE OBJECT ls_rule-regex
EXPORTING
pattern = iv_regex
ignore_case = abap_true.
ls_rule-token = iv_token.
ls_rule-style = iv_style.
APPEND ls_rule TO mt_rules.
ENDMETHOD.
METHOD apply_style.
DATA lv_escaped TYPE string.
lv_escaped = escape( val = iv_line format = cl_abap_format=>e_html_attr ).
IF iv_class IS NOT INITIAL.
rv_line = |<span class="{ iv_class }">{ lv_escaped }</span>|.
ELSE.
rv_line = lv_escaped.
ENDIF.
ENDMETHOD.
METHOD create.
" Create instance of highighter dynamically dependent on syntax type
IF iv_filename CP '*.abap'.
CREATE OBJECT ro_instance TYPE zcl_abapgit_syntax_abap.
ELSEIF iv_filename CP '*.xml'.
CREATE OBJECT ro_instance TYPE zcl_abapgit_syntax_xml.
ELSE.
CLEAR ro_instance.
ENDIF.
ENDMETHOD.
METHOD extend_matches.
DATA: lv_line_len TYPE i,
lv_last_pos TYPE i VALUE 0,
lv_length TYPE i,
ls_match TYPE ty_match.
FIELD-SYMBOLS <ls_match> TYPE ty_match.
lv_line_len = strlen( iv_line ).
SORT ct_matches BY offset.
" Add entries refering to parts of text that should not be formatted
LOOP AT ct_matches ASSIGNING <ls_match>.
IF <ls_match>-offset > lv_last_pos.
lv_length = <ls_match>-offset - lv_last_pos.
ls_match-token = c_token_none.
ls_match-offset = lv_last_pos.
ls_match-length = lv_length.
INSERT ls_match INTO ct_matches INDEX sy-tabix.
ENDIF.
lv_last_pos = <ls_match>-offset + <ls_match>-length.
ENDLOOP.
" Add remainder of the string
IF lv_line_len > lv_last_pos.
lv_length = lv_line_len - lv_last_pos.
ls_match-token = c_token_none.
ls_match-offset = lv_last_pos.
ls_match-length = lv_length.
APPEND ls_match TO ct_matches.
ENDIF.
ENDMETHOD.
METHOD format_line.
DATA:
lv_chunk TYPE string,
ls_rule LIKE LINE OF mt_rules.
FIELD-SYMBOLS <ls_match> TYPE ty_match.
LOOP AT it_matches ASSIGNING <ls_match>.
lv_chunk = substring( val = iv_line off = <ls_match>-offset len = <ls_match>-length ).
CLEAR ls_rule. " Failed read equals no style
READ TABLE mt_rules INTO ls_rule WITH KEY token = <ls_match>-token.
lv_chunk = me->apply_style( iv_line = lv_chunk
iv_class = ls_rule-style ).
rv_line = rv_line && lv_chunk.
ENDLOOP.
ENDMETHOD.
METHOD parse_line.
DATA:
lo_regex TYPE REF TO cl_abap_regex,
lo_matcher TYPE REF TO cl_abap_matcher,
lt_result TYPE match_result_tab,
ls_match TYPE ty_match.
FIELD-SYMBOLS:
<ls_regex> LIKE LINE OF mt_rules,
<ls_result> TYPE match_result.
CLEAR et_matches.
" Process syntax-dependent regex table and find all matches
LOOP AT mt_rules ASSIGNING <ls_regex>.
lo_regex = <ls_regex>-regex.
lo_matcher = lo_regex->create_matcher( text = iv_line ).
lt_result = lo_matcher->find_all( ).
" Save matches into custom table with predefined tokens
LOOP AT lt_result ASSIGNING <ls_result>.
CLEAR: ls_match.
ls_match-token = <ls_regex>-token.
ls_match-offset = <ls_result>-offset.
ls_match-length = <ls_result>-length.
APPEND ls_match TO et_matches.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
METHOD process_line.
DATA: lt_matches TYPE ty_match_tt.
IF strlen( iv_line ) = 0.
RETURN.
ENDIF.
me->parse_line( EXPORTING iv_line = iv_line
IMPORTING et_matches = lt_matches ).
me->order_matches( EXPORTING iv_line = iv_line
CHANGING ct_matches = lt_matches ).
me->extend_matches( EXPORTING iv_line = iv_line
CHANGING ct_matches = lt_matches ).
rv_line = me->format_line( iv_line = iv_line
it_matches = lt_matches ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_SYNTAX_ABAP IMPLEMENTATION.
METHOD class_constructor.
init_keywords( ).
ENDMETHOD.
METHOD constructor.
super->constructor( ).
" Initialize instances of regular expression
add_rule( iv_regex = c_regex-keyword
iv_token = c_token-keyword
iv_style = c_css-keyword ).
add_rule( iv_regex = c_regex-comment
iv_token = c_token-comment
iv_style = c_css-comment ).
add_rule( iv_regex = c_regex-text
iv_token = c_token-text
iv_style = c_css-text ).
ENDMETHOD.
METHOD init_keywords.
DATA: lv_keywords TYPE string,
lt_keywords TYPE STANDARD TABLE OF string.
lv_keywords =
'&&|?TO|ABAP-SOURCE|ABBREVIATED|ABS|ABSTRACT|ACCEPT|ACCEPTING|ACCESSPOLICY' &&
'|ACCORDING|ACOS|ACTIVATION|ACTUAL|ADD|ADD-CORRESPONDING|ADJACENT|AFTER|ALIAS' &&
'|ALIASES|ALIGN|ALL|ALLOCATE|ALPHA|ANALYSIS|ANALYZER|AND|ANY|APPEND|APPENDAGE' &&
'|APPENDING|APPLICATION|ARCHIVE|AREA|ARITHMETIC|AS|ASCENDING|ASIN|ASPECT|ASSERT' &&
'|ASSIGN|ASSIGNED|ASSIGNING|ASSOCIATION|ASYNCHRONOUS|AT|ATAN|ATTRIBUTES|AUTHORITY' &&
'|AUTHORITY-CHECK|AVG|BACK|BACKGROUND|BACKUP|BACKWARD|BADI|BASE|BEFORE|BEGIN' &&
'|BETWEEN|BIG|BINARY|BINDING|BIT|BIT-AND|BIT-NOT|BIT-OR|BIT-XOR|BLACK|BLANK' &&
'|BLANKS|BLOB|BLOCK|BLOCKS|BLUE|BOUND|BOUNDARIES|BOUNDS|BOXED|BREAK-POINT|BT' &&
'|BUFFER|BY|BYPASSING|BYTE|BYTE-CA|BYTE-CN|BYTE-CO|BYTE-CS|BYTE-NA|BYTE-NS' &&
'|BYTE-ORDER|C|CA|CALL|CALLING|CASE|CAST|CASTING|CATCH|CEIL|CENTER|CENTERED' &&
'|CHAIN|CHAIN-INPUT|CHAIN-REQUEST|CHANGE|CHANGING|CHANNELS|CHARACTER|CHARLEN' &&
'|CHAR-TO-HEX|CHECK|CHECKBOX|CI_|CIRCULAR|CLASS|CLASS-CODING|CLASS-DATA' &&
'|CLASS-EVENTS|CLASS-METHODS|CLASS-POOL|CLEANUP|CLEAR|CLIENT|CLOB|CLOCK|CLOSE' &&
'|CN|CNT|CO|COALESCE|CODE|CODING|COL_BACKGROUND|COL_GROUP|COL_HEADING|COL_KEY' &&
'|COL_NEGATIVE|COL_NORMAL|COL_POSITIVE|COL_TOTAL|COLLECT|COLOR|COLUMN|COLUMNS' &&
'|COMMENT|COMMENTS|COMMIT|COMMON|COMMUNICATION|COMPARING|COMPONENT|COMPONENTS' &&
'|COMPRESSION|COMPUTE|CONCAT|CONCATENATE|COND|CONDENSE|CONDITION|CONNECT' &&
'|CONNECTION|CONSTANTS|CONTEXT|CONTEXTS|CONTINUE|CONTROL|CONTROLS|CONV|CONVERSION' &&
'|CONVERT|COPIES|COPY|CORRESPONDING|COS|COSH|COUNT|COUNTRY|COVER|CP|CPI|CREATE' &&
'|CREATING|CRITICAL|CS|CURRENCY|CURRENCY_CONVERSION|CURRENT|CURSOR|CURSOR-SELECTION' &&
'|CUSTOMER|CUSTOMER-FUNCTION|DANGEROUS|DATA|DATABASE|DATAINFO|DATASET|DATE' &&
'|DAYLIGHT|DBMAXLEN|DD/MM/YY|DD/MM/YYYY|DDMMYY|DEALLOCATE|DECIMAL_SHIFT|DECIMALS' &&
'|DECLARATIONS|DEEP|DEFAULT|DEFERRED|DEFINE|DEFINING|DEFINITION|DELETE|DELETING' &&
'|DEMAND|DEPARTMENT|DESCENDING|DESCRIBE|DESTINATION|DETAIL|DIALOG|DIRECTORY' &&
'|DISCONNECT|DISPLAY|DISPLAY-MODE|DISTANCE|DISTINCT|DIV|DIVIDE|DIVIDE-CORRESPONDING' &&
'|DIVISION|DO|DUMMY|DUPLICATE|DUPLICATES|DURATION|DURING|DYNAMIC|DYNPRO|E|EACH' &&
'|EDIT|EDITOR-CALL|ELSE|ELSEIF|EMPTY|ENABLED|ENABLING|ENCODING|END|ENDAT|ENDCASE' &&
'|ENDCATCH|ENDCHAIN|ENDCLASS|ENDDO|ENDENHANCEMENT|END-ENHANCEMENT-SECTION' &&
'|ENDEXEC|ENDFOR|ENDFORM|ENDFUNCTION|ENDIAN|ENDIF|ENDING|ENDINTERFACE' &&
'|END-LINES|ENDLOOP|ENDMETHOD|ENDMODULE|END-OF-DEFINITION|END-OF-FILE' &&
'|END-OF-PAGE|END-OF-SELECTION|ENDON|ENDPROVIDE|ENDSELECT|ENDTRY|ENDWHILE' &&
'|ENGINEERING|ENHANCEMENT|ENHANCEMENT-POINT|ENHANCEMENTS|ENHANCEMENT-SECTION' &&
'|ENTRIES|ENTRY|ENVIRONMENT|EQ|EQUAL|EQUIV|ERRORMESSAGE|ERRORS|ESCAPE|ESCAPING' &&
'|EVENT|EVENTS|EXACT|EXCEPT|EXCEPTION|EXCEPTIONS|EXCEPTION-TABLE|EXCLUDE|EXCLUDING' &&
'|EXEC|EXECUTE|EXISTS|EXIT|EXIT-COMMAND|EXP|EXPAND|EXPANDING|EXPIRATION|EXPLICIT' &&
'|EXPONENT|EXPORT|EXPORTING|EXTEND|EXTENDED|EXTENSION|EXTRACT|FAIL|FETCH|FIELD' &&
'|FIELD-GROUPS|FIELDS|FIELD-SYMBOL|FIELD-SYMBOLS|FILE|FILTER|FILTERS|FILTER-TABLE' &&
'|FINAL|FIND|FIRST|FIRST-LINE|FIXED-POINT|FKEQ|FKGE|FLOOR|FLUSH|FONT|FOR|FORM' &&
'|FORMAT|FORWARD|FOUND|FRAC|FRAME|FRAMES|FREE|FRIENDS|FROM|FUNCTION|FUNCTIONALITY' &&
'|FUNCTION-POOL|FURTHER|GAPS|GE|GENERATE|GET|GIVING|GKEQ|GKGE|GLOBAL|GRANT|GREATER' &&
'|GREEN|GROUP|GROUPS|GT|HANDLE|HANDLER|HARMLESS|HASHED|HAVING|HDB|HEADER|HEADERS' &&
'|HEADING|HEAD-LINES|HELP-ID|HELP-REQUEST|HIDE|HIGH|HINT|HOLD|HOTSPOT|I|ICON|ID' &&
'|IDENTIFICATION|IDENTIFIER|IDS|IF|IGNORE|IGNORING|IMMEDIATELY|IMPLEMENTATION' &&
'|IMPLEMENTATIONS|IMPLEMENTED|IMPLICIT|IMPORT|IMPORTING|IN|INACTIVE|INCL|INCLUDE' &&
'|INCLUDES|INCLUDING|INCREMENT|INDEX|INDEX-LINE|INFOTYPES|INHERITING|INIT|INITIAL' &&
'|INITIALIZATION|INNER|INOUT|INPUT|INSERT|INSTANCES|INTENSIFIED|INTERFACE' &&
'|INTERFACE-POOL|INTERFACES|INTERNAL|INTERVALS|INTO|INVERSE|INVERTED-DATE|IS' &&
'|ISO|ITERATOR|ITNO|JOB|JOIN|KEEP|KEEPING|KERNEL|KEY|KEYS|KEYWORDS|KIND' &&
'|LANGUAGE|LAST|LATE|LAYOUT|LE|LEADING|LEAVE|LEFT|LEFT-JUSTIFIED|LEFTPLUS' &&
'|LEFTSPACE|LEGACY|LENGTH|LESS|LET|LEVEL|LEVELS|LIKE|LINE|LINE-COUNT|LINEFEED' &&
'|LINES|LINE-SELECTION|LINE-SIZE|LIST|LISTBOX|LIST-PROCESSING|LITTLE|LLANG' &&
'|LOAD|LOAD-OF-PROGRAM|LOB|LOCAL|LOCALE|LOCATOR|LOG|LOG10|LOGFILE|LOGICAL' &&
'|LOG-POINT|LONG|LOOP|LOW|LOWER|LPAD|LPI|LT|M|MAIL|MAIN|MAJOR-ID|MAPPING|MARGIN' &&
'|MARK|MASK|MATCH|MATCHCODE|MAX|MAXIMUM|MEDIUM|MEMBERS|MEMORY|MESH|MESSAGE' &&
'|MESSAGE-ID|MESSAGES|MESSAGING|METHOD|METHODS|MIN|MINIMUM|MINOR-ID|MM/DD/YY' &&
'|MM/DD/YYYY|MMDDYY|MOD|MODE|MODIF|MODIFIER|MODIFY|MODULE|MOVE|MOVE-CORRESPONDING' &&
'|MULTIPLY|MULTIPLY-CORRESPONDING|NA|NAME|NAMETAB|NATIVE|NB|NE|NESTED|NESTING' &&
'|NEW|NEW-LINE|NEW-PAGE|NEW-SECTION|NEXT|NO|NODE|NODES|NO-DISPLAY' &&
'|NO-EXTENSION|NO-GAP|NO-GAPS|NO-GROUPING|NO-HEADING|NON-UNICODE|NON-UNIQUE' &&
'|NO-SCROLLING|NO-SIGN|NOT|NO-TITLE|NO-TOPOFPAGE|NO-ZERO|NP|NS|NULL|NUMBER' &&
'|NUMOFCHAR|O|OBJECT|OBJECTS|OBLIGATORY|OCCURRENCE|OCCURRENCES|OCCURS|OF|OFF' &&
'|OFFSET|OLE|ON|ONLY|OPEN|OPTION|OPTIONAL|OPTIONS|OR|ORDER|OTHER|OTHERS|OUT' &&
'|OUTER|OUTPUT|OUTPUT-LENGTH|OVERFLOW|OVERLAY|PACK|PACKAGE|PAD|PADDING|PAGE' &&
'|PAGES|PARAMETER|PARAMETERS|PARAMETER-TABLE|PART|PARTIALLY|PATTERN|PERCENTAGE' &&
'|PERFORM|PERFORMING|PERSON|PF|PF-STATUS|PINK|PLACES|POOL|POS_HIGH|POS_LOW' &&
'|POSITION|PRAGMAS|PRECOMPILED|PREFERRED|PRESERVING|PRIMARY|PRINT|PRINT-CONTROL' &&
'|PRIORITY|PRIVATE|PROCEDURE|PROCESS|PROGRAM|PROPERTY|PROTECTED|PROVIDE|PUBLIC' &&
'|PUSHBUTTON|PUT|QUEUE-ONLY|QUICKINFO|RADIOBUTTON|RAISE|RAISING|RANGE|RANGES' &&
'|RAW|READ|READER|READ-ONLY|RECEIVE|RECEIVED|RECEIVER|RECEIVING|RED|REDEFINITION' &&
'|REDUCE|REDUCED|REF|REFERENCE|REFRESH|REGEX|REJECT|REMOTE|RENAMING|REPLACE' &&
'|REPLACEMENT|REPLACING|REPORT|REQUEST|REQUESTED|RESERVE|RESET|RESOLUTION' &&
'|RESPECTING|RESPONSIBLE|RESULT|RESULTS|RESUMABLE|RESUME|RETRY|RETURN|RETURNCODE' &&
'|RETURNING|RIGHT|RIGHT-JUSTIFIED|RIGHTPLUS|RIGHTSPACE|RISK|RMC_COMMUNICATION_FAILURE' &&
'|RMC_INVALID_STATUS|RMC_SYSTEM_FAILURE|ROLE|ROLLBACK|ROUND|ROWS|RTTI|RUN|SAP' &&
'|SAP-SPOOL|SAVING|SCALE_PRESERVING|SCALE_PRESERVING_SCIENTIFIC|SCAN|SCIENTIFIC' &&
'|SCIENTIFIC_WITH_LEADING_ZERO|SCREEN|SCROLL|SCROLL-BOUNDARY|SCROLLING|SEARCH' &&
'|SECONDARY|SECONDS|SECTION|SELECT|SELECTION|SELECTIONS|SELECTION-SCREEN|SELECTION-SET' &&
'|SELECTION-SETS|SELECTION-TABLE|SELECT-OPTIONS|SELECTOR|SEND|SEPARATE|SEPARATED|SET' &&
'|SHARED|SHIFT|SHORT|SHORTDUMP-ID|SIGN|SIGN_AS_POSTFIX|SIMPLE|SIN|SINGLE|SINH|SIZE' &&
'|SKIP|SKIPPING|SMART|SOME|SORT|SORTABLE|SORTED|SOURCE|SPACE|SPECIFIED|SPLIT|SPOOL' &&
'|SPOTS|SQL|SQLSCRIPT|SQRT|STABLE|STAMP|STANDARD|STARTING|START-OF-SELECTION|STATE' &&
'|STATEMENT|STATEMENTS|STATIC|STATICS|STATUSINFO|STEP-LOOP|STOP|STRLEN|STRUCTURE' &&
'|STRUCTURES|STYLE|SUBKEY|SUBMATCHES|SUBMIT|SUBROUTINE|SUBSCREEN|SUBSTRING|SUBTRACT' &&
'|SUBTRACT-CORRESPONDING|SUFFIX|SUM|SUMMARY|SUMMING|SUPPLIED|SUPPLY|SUPPRESS|SWITCH' &&
'|SWITCHSTATES|SYMBOL|SYNCPOINTS|SYNTAX|SYNTAX-CHECK|SYNTAX-TRACE' &&
'|SYSTEM-CALL|SYSTEM-EXCEPTIONS|SYSTEM-EXIT|TAB|TABBED|TABLE|TABLES|TABLEVIEW|TABSTRIP' &&
'|TAN|TANH|TARGET|TASK|TASKS|TEST|TESTING|TEXT|TEXTPOOL|THEN|THROW|TIME|TIMES|TIMESTAMP' &&
'|TIMEZONE|TITLE|TITLEBAR|TITLE-LINES|TO|TOKENIZATION|TOKENS|TOP-LINES|TOP-OF-PAGE' &&
'|TRACE-FILE|TRACE-TABLE|TRAILING|TRANSACTION|TRANSFER|TRANSFORMATION|TRANSLATE' &&
'|TRANSPORTING|TRMAC|TRUNC|TRUNCATE|TRUNCATION|TRY|TYPE|TYPE-POOL|TYPE-POOLS|TYPES' &&
'|ULINE|UNASSIGN|UNDER|UNICODE|UNION|UNIQUE|UNIT|UNIT_CONVERSION|UNIX|UNPACK|UNTIL' &&
'|UNWIND|UP|UPDATE|UPPER|USER|USER-COMMAND|USING|UTF-8|VALID|VALUE|VALUE-REQUEST|VALUES' &&
'|VARY|VARYING|VERIFICATION-MESSAGE|VERSION|VIA|VIEW|VISIBLE|WAIT|WARNING|WHEN|WHENEVER' &&
'|WHERE|WHILE|WIDTH|WINDOW|WINDOWS|WITH|WITH-HEADING|WITHOUT|WITH-TITLE|WORD|WORK' &&
'|WRITE|WRITER|X|XML|XOR|XSD|XSTRLEN|YELLOW|YES|YYMMDD|Z|ZERO|ZONE'.
SPLIT lv_keywords AT '|' INTO TABLE lt_keywords.
gt_keywords = lt_keywords. " Hash table
ENDMETHOD.
METHOD is_keyword.
DATA lv_str TYPE string.
lv_str = to_upper( iv_chunk ).
READ TABLE gt_keywords WITH KEY table_line = lv_str TRANSPORTING NO FIELDS.
rv_yes = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD order_matches.
DATA:
lv_index TYPE sy-tabix,
lv_line_len TYPE i,
lv_prev_token TYPE c.
FIELD-SYMBOLS:
<ls_prev> TYPE ty_match,
<ls_match> TYPE ty_match.
SORT ct_matches BY offset.
lv_line_len = strlen( iv_line ).
LOOP AT ct_matches ASSIGNING <ls_match>.
lv_index = sy-tabix.
" Delete matches after open text match
IF lv_prev_token = c_token-text AND <ls_match>-token <> c_token-text.
DELETE ct_matches INDEX lv_index.
CONTINUE.
ENDIF.
CASE <ls_match>-token.
WHEN c_token-keyword.
IF <ls_match>-offset > 0
AND substring( val = iv_line off = ( <ls_match>-offset - 1 ) len = 1 ) CA '-<'.
" Delete match if keyword is part of structure or field symbol
DELETE ct_matches INDEX lv_index.
CONTINUE.
ENDIF.
WHEN c_token-comment.
<ls_match>-length = lv_line_len - <ls_match>-offset.
DELETE ct_matches FROM lv_index + 1.
CONTINUE.
WHEN c_token-text.
<ls_match>-text_tag = substring( val = iv_line
off = <ls_match>-offset
len = <ls_match>-length ).
IF lv_prev_token = c_token-text.
IF <ls_match>-text_tag = <ls_prev>-text_tag.
<ls_prev>-length = <ls_match>-offset + <ls_match>-length - <ls_prev>-offset.
CLEAR lv_prev_token.
ELSEIF <ls_prev>-text_tag = '}' AND <ls_match>-text_tag = '{'.
<ls_prev>-length = <ls_match>-offset - <ls_prev>-offset - 1. " Shift } out of scope
<ls_prev>-offset = <ls_prev>-offset + 1. " Shift { out of scope
CLEAR lv_prev_token.
ELSEIF <ls_match>-text_tag = '{'.
<ls_prev>-length = <ls_match>-offset - <ls_prev>-offset.
CLEAR lv_prev_token.
ELSEIF <ls_prev>-text_tag = '}'.
<ls_prev>-length = <ls_match>-offset - <ls_prev>-offset.
<ls_prev>-offset = <ls_prev>-offset + 1. " Shift } out of scope
CLEAR lv_prev_token.
ENDIF.
DELETE ct_matches INDEX lv_index.
CONTINUE.
ENDIF.
ENDCASE.
lv_prev_token = <ls_match>-token.
ASSIGN <ls_match> TO <ls_prev>.
ENDLOOP.
ENDMETHOD.
METHOD parse_line. "REDEFINITION
DATA lv_index TYPE i.
FIELD-SYMBOLS <ls_match> LIKE LINE OF et_matches.
super->parse_line( EXPORTING iv_line = iv_line
IMPORTING et_matches = et_matches ).
" Remove non-keywords
LOOP AT et_matches ASSIGNING <ls_match> WHERE token = c_token-keyword.
lv_index = sy-tabix.
IF abap_false = is_keyword( substring( val = iv_line
off = <ls_match>-offset
len = <ls_match>-length ) ).
DELETE et_matches INDEX lv_index.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PERSISTENCE_USER IMPLEMENTATION.
METHOD constructor.
mv_user = iv_user.
ENDMETHOD.
METHOD from_xml.
DATA: lv_xml TYPE string.
lv_xml = iv_xml.
REPLACE ALL OCCURRENCES OF '<_--28C_TYPE_USER_--29>' IN lv_xml WITH '<USER>'.
REPLACE ALL OCCURRENCES OF '</_--28C_TYPE_USER_--29>' IN lv_xml WITH '</USER>'.
CALL TRANSFORMATION id
OPTIONS value_handling = 'accept_data_loss'
SOURCE XML lv_xml
RESULT user = rs_user ##NO_TEXT.
ENDMETHOD.
METHOD get_instance.
IF iv_user = sy-uname ##USER_OK.
IF gi_current_user IS NOT BOUND.
CREATE OBJECT gi_current_user TYPE zcl_abapgit_persistence_user.
ENDIF.
ri_user = gi_current_user.
ELSE.
CREATE OBJECT ri_user TYPE zcl_abapgit_persistence_user
EXPORTING
iv_user = iv_user.
ENDIF.
ENDMETHOD.
METHOD read.
DATA: lv_xml TYPE string.
TRY.
lv_xml = zcl_abapgit_persistence_db=>get_instance( )->read(
iv_type = zcl_abapgit_persistence_db=>c_type_user
iv_value = mv_user ).
CATCH zcx_abapgit_not_found.
RETURN.
ENDTRY.
rs_user = from_xml( lv_xml ).
ENDMETHOD.
METHOD read_repo_config.
DATA: lt_repo_config TYPE ty_repo_config_tt,
lv_key TYPE string.
lv_key = to_lower( iv_url ).
lt_repo_config = read( )-repo_config.
READ TABLE lt_repo_config INTO rs_repo_config WITH KEY url = lv_key.
ENDMETHOD. "read_repo_config
METHOD to_xml.
CALL TRANSFORMATION id
SOURCE user = is_user
RESULT XML rv_xml.
ENDMETHOD.
METHOD update.
DATA: lv_xml TYPE string.
lv_xml = to_xml( is_user ).
zcl_abapgit_persistence_db=>get_instance( )->modify(
iv_type = zcl_abapgit_persistence_db=>c_type_user
iv_value = mv_user
iv_data = lv_xml ).
ENDMETHOD.
METHOD update_repo_config.
DATA: ls_user TYPE ty_user,
lv_key TYPE string.
FIELD-SYMBOLS <ls_repo_config> TYPE ty_repo_config.
ls_user = read( ).
lv_key = to_lower( iv_url ).
READ TABLE ls_user-repo_config ASSIGNING <ls_repo_config> WITH KEY url = lv_key.
IF sy-subrc IS NOT INITIAL.
APPEND INITIAL LINE TO ls_user-repo_config ASSIGNING <ls_repo_config>.
ENDIF.
<ls_repo_config> = is_repo_config.
<ls_repo_config>-url = lv_key.
update( ls_user ).
COMMIT WORK AND WAIT.
ENDMETHOD. "update_repo_config
METHOD zif_abapgit_persist_user~get_changes_only.
rv_changes_only = read( )-changes_only.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_default_git_user_email.
rv_email = read( )-default_git_user-email.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_default_git_user_name.
rv_username = read( )-default_git_user-name.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_diff_unified.
rv_diff_unified = read( )-diff_unified.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_favorites.
rt_favorites = read( )-favorites.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_hide_files.
rv_hide = read( )-hide_files.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_repo_git_user_email.
rv_email = read_repo_config( iv_url )-git_user-email.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_repo_git_user_name.
rv_username = read_repo_config( iv_url )-git_user-name.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_repo_last_change_seen.
rv_version = read_repo_config( iv_url )-last_change_seen.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_repo_login.
rv_login = read_repo_config( iv_url )-login.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_repo_show.
rv_key = read( )-repo_show.
ENDMETHOD.
METHOD zif_abapgit_persist_user~get_settings.
DATA: ls_user TYPE ty_user.
ls_user = read( ).
rs_user_settings = ls_user-settings.
ENDMETHOD.
METHOD zif_abapgit_persist_user~is_favorite_repo.
DATA: lt_favorites TYPE tt_favorites.
lt_favorites = zif_abapgit_persist_user~get_favorites( ).
READ TABLE lt_favorites TRANSPORTING NO FIELDS
WITH KEY table_line = iv_repo_key.
rv_yes = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_persist_user~set_default_git_user_email.
DATA: ls_user TYPE ty_user.
ls_user = read( ).
ls_user-default_git_user-email = iv_email.
update( ls_user ).
ENDMETHOD.
METHOD zif_abapgit_persist_user~set_default_git_user_name.
DATA: ls_user TYPE ty_user.
ls_user = read( ).
ls_user-default_git_user-name = iv_username.
update( ls_user ).
ENDMETHOD.
METHOD zif_abapgit_persist_user~set_repo_git_user_email.
DATA: ls_repo_config TYPE ty_repo_config.
ls_repo_config = read_repo_config( iv_url ).
ls_repo_config-git_user-email = iv_email.
update_repo_config( iv_url = iv_url is_repo_config = ls_repo_config ).
ENDMETHOD.
METHOD zif_abapgit_persist_user~set_repo_git_user_name.
DATA: ls_repo_config TYPE ty_repo_config.
ls_repo_config = read_repo_config( iv_url ).
ls_repo_config-git_user-name = iv_username.
update_repo_config( iv_url = iv_url is_repo_config = ls_repo_config ).
ENDMETHOD.
METHOD zif_abapgit_persist_user~set_repo_last_change_seen.
DATA: ls_repo_config TYPE ty_repo_config.
ls_repo_config = read_repo_config( iv_url ).
ls_repo_config-last_change_seen = iv_version.
update_repo_config( iv_url = iv_url is_repo_config = ls_repo_config ).
ENDMETHOD.
METHOD zif_abapgit_persist_user~set_repo_login.
DATA: ls_repo_config TYPE ty_repo_config.
ls_repo_config = read_repo_config( iv_url ).
ls_repo_config-login = iv_login.
update_repo_config( iv_url = iv_url is_repo_config = ls_repo_config ).
ENDMETHOD.
METHOD zif_abapgit_persist_user~set_repo_show.
DATA: ls_user TYPE ty_user.
ls_user = read( ).
ls_user-repo_show = iv_key.
update( ls_user ).
COMMIT WORK AND WAIT.
ENDMETHOD.
METHOD zif_abapgit_persist_user~set_settings.
DATA: ls_user TYPE ty_user.
ls_user = read( ).
ls_user-settings = is_user_settings.
update( ls_user ).
ENDMETHOD.
METHOD zif_abapgit_persist_user~toggle_changes_only.
DATA ls_user TYPE ty_user.
ls_user = read( ).
ls_user-changes_only = boolc( ls_user-changes_only = abap_false ).
update( ls_user ).
rv_changes_only = ls_user-changes_only.
ENDMETHOD.
METHOD zif_abapgit_persist_user~toggle_diff_unified.
DATA ls_user TYPE ty_user.
ls_user = read( ).
ls_user-diff_unified = boolc( ls_user-diff_unified = abap_false ).
update( ls_user ).
rv_diff_unified = ls_user-diff_unified.
ENDMETHOD.
METHOD zif_abapgit_persist_user~toggle_favorite.
DATA: ls_user TYPE ty_user.
ls_user = read( ).
READ TABLE ls_user-favorites TRANSPORTING NO FIELDS
WITH KEY table_line = iv_repo_key.
IF sy-subrc = 0.
DELETE ls_user-favorites INDEX sy-tabix.
ELSE.
APPEND iv_repo_key TO ls_user-favorites.
ENDIF.
update( ls_user ).
COMMIT WORK AND WAIT.
ENDMETHOD.
METHOD zif_abapgit_persist_user~toggle_hide_files.
DATA ls_user TYPE ty_user.
ls_user = read( ).
ls_user-hide_files = boolc( ls_user-hide_files = abap_false ).
update( ls_user ).
rv_hide = ls_user-hide_files.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PERSISTENCE_REPO IMPLEMENTATION.
METHOD constructor.
mo_db = zcl_abapgit_persistence_db=>get_instance( ).
ENDMETHOD.
METHOD from_xml.
DATA: lv_xml TYPE string.
lv_xml = iv_repo_xml_string.
REPLACE ALL OCCURRENCES OF '<_--28C_TYPE_REPO_--29>' IN lv_xml WITH '<REPO>'.
REPLACE ALL OCCURRENCES OF '</_--28C_TYPE_REPO_--29>' IN lv_xml WITH '</REPO>'.
CALL TRANSFORMATION id
OPTIONS value_handling = 'accept_data_loss'
SOURCE XML lv_xml
RESULT repo = rs_repo ##NO_TEXT.
FIND FIRST OCCURRENCE OF '</HEAD_BRANCH><WRITE_PROTECT>X</WRITE_PROTECT>' IN lv_xml.
IF sy-subrc = 0.
rs_repo-local_settings-write_protected = abap_true.
ENDIF.
FIND FIRST OCCURRENCE OF '<IGNORE_SUBPACKAGES>X</IGNORE_SUBPACKAGES></REPO>' IN lv_xml.
IF sy-subrc = 0.
rs_repo-local_settings-ignore_subpackages = abap_true.
ENDIF.
IF rs_repo IS INITIAL.
zcx_abapgit_exception=>raise( 'Inconsistent repo metadata' ).
ENDIF.
ENDMETHOD.
METHOD get_next_id.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content.
FIELD-SYMBOLS: <ls_content> LIKE LINE OF lt_content.
rv_next_repo_id = 1.
lt_content = mo_db->list_by_type( zcl_abapgit_persistence_db=>c_type_repo ).
LOOP AT lt_content ASSIGNING <ls_content>.
IF <ls_content>-value >= rv_next_repo_id.
rv_next_repo_id = <ls_content>-value + 1.
ENDIF.
ENDLOOP.
CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
EXPORTING
input = rv_next_repo_id
IMPORTING
output = rv_next_repo_id.
ENDMETHOD.
METHOD to_xml.
DATA: ls_xml TYPE zif_abapgit_persistence=>ty_repo_xml.
MOVE-CORRESPONDING is_repo TO ls_xml.
CALL TRANSFORMATION id
SOURCE repo = ls_xml
RESULT XML rv_repo_xml_string.
ENDMETHOD.
METHOD zif_abapgit_persist_repo~add.
DATA: ls_repo TYPE zif_abapgit_persistence=>ty_repo,
lv_repo_as_xml TYPE string.
ls_repo-url = iv_url.
ls_repo-branch_name = iv_branch_name.
ls_repo-package = iv_package.
ls_repo-offline = iv_offline.
ls_repo-created_by = sy-uname.
GET TIME STAMP FIELD ls_repo-created_at.
ls_repo-dot_abapgit = is_dot_abapgit.
lv_repo_as_xml = to_xml( ls_repo ).
rv_key = get_next_id( ).
mo_db->add( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = rv_key
iv_data = lv_repo_as_xml ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~delete.
DATA: lo_background TYPE REF TO zcl_abapgit_persist_background.
CREATE OBJECT lo_background.
lo_background->delete( iv_key ).
mo_db->delete( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~list.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo LIKE LINE OF rt_repos.
lt_content = mo_db->list_by_type( zcl_abapgit_persistence_db=>c_type_repo ).
LOOP AT lt_content INTO ls_content.
MOVE-CORRESPONDING from_xml( ls_content-data_str ) TO ls_repo.
ls_repo-key = ls_content-value.
INSERT ls_repo INTO TABLE rt_repos.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_persist_repo~lock.
mo_db->lock( iv_mode = iv_mode
iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~read.
DATA lt_repo TYPE zif_abapgit_persistence=>tt_repo.
lt_repo = list( ).
READ TABLE lt_repo INTO rs_repo WITH KEY key = iv_key.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE zcx_abapgit_not_found.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_persist_repo~update_branch_name.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo TYPE zif_abapgit_persistence=>ty_repo.
ASSERT NOT iv_key IS INITIAL.
TRY.
ls_repo = read( iv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'key not found' ).
ENDTRY.
ls_repo-branch_name = iv_branch_name.
ls_content-data_str = to_xml( ls_repo ).
mo_db->update( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key
iv_data = ls_content-data_str ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~update_deserialized.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo TYPE zif_abapgit_persistence=>ty_repo.
ASSERT NOT iv_key IS INITIAL.
TRY.
ls_repo = read( iv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'key not found' ).
ENDTRY.
IF iv_deserialized_at IS NOT INITIAL.
ls_repo-deserialized_at = iv_deserialized_at.
ENDIF.
IF iv_deserialized_by IS NOT INITIAL.
ls_repo-deserialized_by = iv_deserialized_by.
ENDIF.
ls_content-data_str = to_xml( ls_repo ).
mo_db->update( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key
iv_data = ls_content-data_str ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~update_dot_abapgit.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo TYPE zif_abapgit_persistence=>ty_repo.
ASSERT NOT iv_key IS INITIAL.
TRY.
ls_repo = read( iv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'key not found' ).
ENDTRY.
ls_repo-dot_abapgit = is_dot_abapgit.
ls_content-data_str = to_xml( ls_repo ).
mo_db->update( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key
iv_data = ls_content-data_str ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~update_head_branch.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo TYPE zif_abapgit_persistence=>ty_repo.
ASSERT NOT iv_key IS INITIAL.
TRY.
ls_repo = read( iv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'key not found' ).
ENDTRY.
ls_repo-head_branch = iv_head_branch.
ls_content-data_str = to_xml( ls_repo ).
mo_db->update( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key
iv_data = ls_content-data_str ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~update_local_checksums.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo TYPE zif_abapgit_persistence=>ty_repo.
ASSERT NOT iv_key IS INITIAL.
TRY.
ls_repo = read( iv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'key not found' ).
ENDTRY.
ls_repo-local_checksums = it_checksums.
ls_content-data_str = to_xml( ls_repo ).
mo_db->update( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key
iv_data = ls_content-data_str ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~update_local_settings.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo TYPE zif_abapgit_persistence=>ty_repo.
ASSERT NOT iv_key IS INITIAL.
TRY.
ls_repo = read( iv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'key not found' ).
ENDTRY.
ls_repo-local_settings = is_settings.
ls_content-data_str = to_xml( ls_repo ).
mo_db->update( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key
iv_data = ls_content-data_str ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~update_offline.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo TYPE zif_abapgit_persistence=>ty_repo.
ASSERT NOT iv_key IS INITIAL.
TRY.
ls_repo = read( iv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'key not found' ).
ENDTRY.
ls_repo-offline = iv_offline.
ls_content-data_str = to_xml( ls_repo ).
mo_db->update( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key
iv_data = ls_content-data_str ).
ENDMETHOD.
METHOD zif_abapgit_persist_repo~update_url.
DATA: lt_content TYPE zif_abapgit_persistence=>tt_content,
ls_content LIKE LINE OF lt_content,
ls_repo TYPE zif_abapgit_persistence=>ty_repo.
IF iv_url IS INITIAL.
zcx_abapgit_exception=>raise( 'update, url empty' ).
ENDIF.
ASSERT NOT iv_key IS INITIAL.
TRY.
ls_repo = read( iv_key ).
CATCH zcx_abapgit_not_found.
zcx_abapgit_exception=>raise( 'key not found' ).
ENDTRY.
ls_repo-url = iv_url.
ls_content-data_str = to_xml( ls_repo ).
mo_db->update( iv_type = zcl_abapgit_persistence_db=>c_type_repo
iv_value = iv_key
iv_data = ls_content-data_str ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PERSISTENCE_DB IMPLEMENTATION.
METHOD add.
DATA ls_table TYPE zif_abapgit_persistence=>ty_content.
ls_table-type = iv_type.
ls_table-value = iv_value.
ls_table-data_str = iv_data.
INSERT (c_tabname) FROM ls_table. "#EC CI_SUBRC
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD delete.
lock( iv_type = iv_type
iv_value = iv_value ).
DELETE FROM (c_tabname)
WHERE type = iv_type
AND value = iv_value.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'DB Delete failed' ).
ENDIF.
ENDMETHOD.
METHOD get_instance.
IF go_db IS NOT BOUND.
CREATE OBJECT go_db.
ENDIF.
ro_db = go_db.
ENDMETHOD.
METHOD list.
SELECT * FROM (c_tabname)
INTO TABLE rt_content. "#EC CI_SUBRC
ENDMETHOD.
METHOD list_by_type.
SELECT * FROM (c_tabname)
INTO TABLE rt_content
WHERE type = iv_type
ORDER BY PRIMARY KEY. "#EC CI_SUBRC
ENDMETHOD.
METHOD lock.
CALL FUNCTION 'ENQUEUE_EZABAPGIT'
EXPORTING
mode_zabapgit = iv_mode
type = iv_type
value = iv_value
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Could not aquire lock { iv_type } { iv_value }| ).
ENDIF.
CALL FUNCTION 'BANK_OBJ_WORKL_RELEASE_LOCKS'
IN UPDATE TASK.
ENDMETHOD.
METHOD modify.
DATA: ls_content TYPE zif_abapgit_persistence=>ty_content.
lock( iv_type = iv_type
iv_value = iv_value ).
ls_content-type = iv_type.
ls_content-value = iv_value.
ls_content-data_str = iv_data.
MODIFY (c_tabname) FROM ls_content.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'DB modify failed' ).
ENDIF.
ENDMETHOD.
METHOD read.
SELECT SINGLE data_str FROM (c_tabname) INTO rv_data
WHERE type = iv_type
AND value = iv_value. "#EC CI_SUBRC
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE zcx_abapgit_not_found.
ENDIF.
ENDMETHOD.
METHOD update.
DATA lv_data LIKE iv_data.
lv_data = validate_and_unprettify_xml( iv_data ).
lock( iv_type = iv_type
iv_value = iv_value ).
UPDATE (c_tabname) SET data_str = lv_data
WHERE type = iv_type
AND value = iv_value.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'DB update failed' ).
ENDIF.
ENDMETHOD. "update
METHOD validate_and_unprettify_xml.
rv_xml = zcl_abapgit_xml_pretty=>print(
iv_xml = iv_xml
iv_unpretty = abap_true
iv_ignore_errors = abap_false ).
ENDMETHOD. " validate_and_unprettify_xml
ENDCLASS.
CLASS zcl_abapgit_persist_settings IMPLEMENTATION.
METHOD get_instance.
IF go_persist IS NOT BOUND.
CREATE OBJECT go_persist.
ENDIF.
ro_settings = go_persist.
ENDMETHOD.
METHOD modify.
DATA: lv_settings TYPE string,
ls_user_settings TYPE zif_abapgit_definitions=>ty_s_user_settings.
lv_settings = io_settings->get_settings_xml( ).
zcl_abapgit_persistence_db=>get_instance( )->modify(
iv_type = zcl_abapgit_persistence_db=>c_type_settings
iv_value = ''
iv_data = lv_settings ).
ls_user_settings = io_settings->get_user_settings( ).
zcl_abapgit_persistence_user=>get_instance( )->set_settings( ls_user_settings ).
" Settings have been modified: Update Buffered Settings
IF mo_settings IS BOUND.
mo_settings->set_xml_settings( lv_settings ).
mo_settings->set_user_settings( ls_user_settings ).
ENDIF.
ENDMETHOD.
METHOD read.
IF mo_settings IS BOUND.
" Return Buffered Settings
ro_settings = mo_settings.
RETURN.
ENDIF.
" Settings have changed or have not yet been loaded
CREATE OBJECT ro_settings.
TRY.
ro_settings->set_xml_settings(
zcl_abapgit_persistence_db=>get_instance( )->read(
iv_type = zcl_abapgit_persistence_db=>c_type_settings
iv_value = '' ) ).
ro_settings->set_user_settings( zcl_abapgit_persistence_user=>get_instance( )->get_settings( ) ).
CATCH zcx_abapgit_not_found zcx_abapgit_exception.
ro_settings->set_defaults( ).
ENDTRY.
mo_settings = ro_settings.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PERSIST_MIGRATE IMPLEMENTATION.
METHOD distribute_settings_to_users.
DATA: lt_abapgit_users TYPE STANDARD TABLE OF char12
WITH NON-UNIQUE DEFAULT KEY,
ls_user_settings TYPE zif_abapgit_definitions=>ty_s_user_settings,
li_user_persistence TYPE REF TO zif_abapgit_persist_user.
FIELD-SYMBOLS: <lv_user> LIKE LINE OF lt_abapgit_users,
<ls_setting_to_migrate> TYPE zcl_abapgit_persist_migrate=>ty_settings_to_migrate,
<lg_user_specific_setting_val> TYPE data.
" distribute settings to all abapGit users
SELECT value FROM (zcl_abapgit_persistence_db=>c_tabname)
INTO TABLE lt_abapgit_users
WHERE type = zcl_abapgit_persistence_db=>c_type_user.
LOOP AT lt_abapgit_users ASSIGNING <lv_user>.
li_user_persistence = zcl_abapgit_persistence_user=>get_instance( <lv_user> ).
ls_user_settings = li_user_persistence->get_settings( ).
LOOP AT it_settings_to_migrate ASSIGNING <ls_setting_to_migrate>.
ASSIGN COMPONENT <ls_setting_to_migrate>-name
OF STRUCTURE ls_user_settings
TO <lg_user_specific_setting_val>.
ASSERT sy-subrc = 0.
<lg_user_specific_setting_val> = <ls_setting_to_migrate>-value.
ENDLOOP.
li_user_persistence->set_settings( ls_user_settings ).
ENDLOOP.
ENDMETHOD.
METHOD get_global_settings_document.
DATA: lv_global_settings_xml TYPE string.
lv_global_settings_xml = read_global_settings_xml( ).
ri_global_settings_dom = cl_ixml_80_20=>parse_to_document( stream_string = lv_global_settings_xml ).
ENDMETHOD.
METHOD lock_create.
DATA: lv_obj_name TYPE tadir-obj_name,
ls_dd25v TYPE dd25v,
lt_dd26e TYPE STANDARD TABLE OF dd26e WITH DEFAULT KEY,
lt_dd27p TYPE STANDARD TABLE OF dd27p WITH DEFAULT KEY.
FIELD-SYMBOLS: <ls_dd26e> LIKE LINE OF lt_dd26e,
<ls_dd27p> LIKE LINE OF lt_dd27p.
ls_dd25v-viewname = zcl_abapgit_persistence_db=>c_lock.
ls_dd25v-aggtype = 'E'.
ls_dd25v-roottab = zcl_abapgit_persistence_db=>c_tabname.
ls_dd25v-ddlanguage = zif_abapgit_definitions=>c_english.
ls_dd25v-ddtext = c_text.
APPEND INITIAL LINE TO lt_dd26e ASSIGNING <ls_dd26e>.
<ls_dd26e>-viewname = zcl_abapgit_persistence_db=>c_lock.
<ls_dd26e>-tabname = zcl_abapgit_persistence_db=>c_tabname.
<ls_dd26e>-tabpos = '0001'.
<ls_dd26e>-fortabname = zcl_abapgit_persistence_db=>c_tabname.
<ls_dd26e>-enqmode = 'E'.
APPEND INITIAL LINE TO lt_dd27p ASSIGNING <ls_dd27p>.
<ls_dd27p>-viewname = zcl_abapgit_persistence_db=>c_lock.
<ls_dd27p>-objpos = '0001'.
<ls_dd27p>-viewfield = 'TYPE'.
<ls_dd27p>-tabname = zcl_abapgit_persistence_db=>c_tabname.
<ls_dd27p>-fieldname = 'TYPE'.
<ls_dd27p>-keyflag = abap_true.
APPEND INITIAL LINE TO lt_dd27p ASSIGNING <ls_dd27p>.
<ls_dd27p>-viewname = zcl_abapgit_persistence_db=>c_lock.
<ls_dd27p>-objpos = '0002'.
<ls_dd27p>-viewfield = 'VALUE'.
<ls_dd27p>-tabname = zcl_abapgit_persistence_db=>c_tabname.
<ls_dd27p>-fieldname = 'VALUE'.
<ls_dd27p>-keyflag = abap_true.
CALL FUNCTION 'DDIF_ENQU_PUT'
EXPORTING
name = zcl_abapgit_persistence_db=>c_lock
dd25v_wa = ls_dd25v
TABLES
dd26e_tab = lt_dd26e
dd27p_tab = lt_dd27p
EXCEPTIONS
enqu_not_found = 1
name_inconsistent = 2
enqu_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'migrate, error from DDIF_ENQU_PUT' ).
ENDIF.
lv_obj_name = zcl_abapgit_persistence_db=>c_lock.
CALL FUNCTION 'TR_TADIR_INTERFACE'
EXPORTING
wi_tadir_pgmid = 'R3TR'
wi_tadir_object = 'ENQU'
wi_tadir_obj_name = lv_obj_name
wi_set_genflag = abap_true
wi_test_modus = abap_false
wi_tadir_devclass = '$TMP'
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'migrate, error from TR_TADIR_INTERFACE' ).
ENDIF.
CALL FUNCTION 'DDIF_ENQU_ACTIVATE'
EXPORTING
name = zcl_abapgit_persistence_db=>c_lock
EXCEPTIONS
not_found = 1
put_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'migrate, error from DDIF_ENQU_ACTIVATE' ).
ENDIF.
ENDMETHOD.
METHOD lock_exists.
DATA: lv_viewname TYPE dd25l-viewname.
SELECT SINGLE viewname FROM dd25l INTO lv_viewname
WHERE viewname = zcl_abapgit_persistence_db=>c_lock.
rv_exists = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD migrate_setting.
DATA: li_element TYPE REF TO if_ixml_element,
ls_setting_to_migrate LIKE LINE OF ct_settings_to_migrate.
li_element = ci_document->find_from_name( iv_name ).
IF li_element IS BOUND.
" The element is present in the global config.
" Therefore we have to migrate it
ls_setting_to_migrate-name = iv_name.
ls_setting_to_migrate-value = li_element->get_value( ).
INSERT ls_setting_to_migrate INTO TABLE ct_settings_to_migrate.
li_element->remove_node( ).
ENDIF.
ENDMETHOD.
METHOD migrate_settings.
DATA: li_global_settings_document TYPE REF TO if_ixml_document,
lt_settings_to_migrate TYPE tty_settings_to_migrate,
lx_error TYPE REF TO zcx_abapgit_not_found.
" migrate global settings to user specific settings
TRY.
li_global_settings_document = get_global_settings_document( ).
CATCH zcx_abapgit_not_found INTO lx_error.
" No global settings available, nothing todo.
RETURN.
ENDTRY.
migrate_setting(
EXPORTING
iv_name = |MAX_LINES|
CHANGING
ct_settings_to_migrate = lt_settings_to_migrate
ci_document = li_global_settings_document ).
migrate_setting(
EXPORTING
iv_name = |ADT_JUMP_ENABLED|
CHANGING
ct_settings_to_migrate = lt_settings_to_migrate
ci_document = li_global_settings_document ).
IF lines( lt_settings_to_migrate ) > 0.
distribute_settings_to_users( lt_settings_to_migrate ).
update_global_settings( li_global_settings_document ).
ENDIF.
ENDMETHOD.
METHOD read_global_settings_xml.
rv_global_settings_xml = zcl_abapgit_persistence_db=>get_instance( )->read(
iv_type = zcl_abapgit_persistence_db=>c_type_settings
iv_value = '' ).
ENDMETHOD.
METHOD run.
IF table_exists( ) = abap_false.
table_create( ).
ENDIF.
IF lock_exists( ) = abap_false.
lock_create( ).
ENDIF.
migrate_settings( ).
ENDMETHOD.
METHOD table_create.
DATA: lv_rc LIKE sy-subrc,
lv_obj_name TYPE tadir-obj_name,
ls_dd02v TYPE dd02v,
ls_dd09l TYPE dd09l,
lt_dd03p TYPE STANDARD TABLE OF dd03p WITH DEFAULT KEY.
FIELD-SYMBOLS: <ls_dd03p> LIKE LINE OF lt_dd03p.
ls_dd02v-tabname = zcl_abapgit_persistence_db=>c_tabname.
ls_dd02v-ddlanguage = zif_abapgit_definitions=>c_english.
ls_dd02v-tabclass = 'TRANSP'.
ls_dd02v-ddtext = c_text.
ls_dd02v-contflag = 'L'.
ls_dd02v-exclass = '1'.
ls_dd09l-tabname = zcl_abapgit_persistence_db=>c_tabname.
ls_dd09l-as4local = 'A'.
ls_dd09l-tabkat = '1'.
ls_dd09l-tabart = 'APPL1'.
ls_dd09l-bufallow = 'N'.
APPEND INITIAL LINE TO lt_dd03p ASSIGNING <ls_dd03p>.
<ls_dd03p>-tabname = zcl_abapgit_persistence_db=>c_tabname.
<ls_dd03p>-fieldname = 'TYPE'.
<ls_dd03p>-position = '0001'.
<ls_dd03p>-keyflag = 'X'.
<ls_dd03p>-datatype = 'CHAR'.
<ls_dd03p>-leng = '000012'.
APPEND INITIAL LINE TO lt_dd03p ASSIGNING <ls_dd03p>.
<ls_dd03p>-tabname = zcl_abapgit_persistence_db=>c_tabname.
<ls_dd03p>-fieldname = 'VALUE'.
<ls_dd03p>-position = '0002'.
<ls_dd03p>-keyflag = 'X'.
<ls_dd03p>-datatype = 'CHAR'.
<ls_dd03p>-leng = '000012'.
APPEND INITIAL LINE TO lt_dd03p ASSIGNING <ls_dd03p>.
<ls_dd03p>-tabname = zcl_abapgit_persistence_db=>c_tabname.
<ls_dd03p>-fieldname = 'DATA_STR'.
<ls_dd03p>-position = '0003'.
<ls_dd03p>-datatype = 'STRG'.
CALL FUNCTION 'DDIF_TABL_PUT'
EXPORTING
name = zcl_abapgit_persistence_db=>c_tabname
dd02v_wa = ls_dd02v
dd09l_wa = ls_dd09l
TABLES
dd03p_tab = lt_dd03p
EXCEPTIONS
tabl_not_found = 1
name_inconsistent = 2
tabl_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'migrate, error from DDIF_TABL_PUT' ).
ENDIF.
lv_obj_name = zcl_abapgit_persistence_db=>c_tabname.
CALL FUNCTION 'TR_TADIR_INTERFACE'
EXPORTING
wi_tadir_pgmid = 'R3TR'
wi_tadir_object = 'TABL'
wi_tadir_obj_name = lv_obj_name
wi_set_genflag = abap_true
wi_test_modus = abap_false
wi_tadir_devclass = '$TMP'
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'migrate, error from TR_TADIR_INTERFACE' ).
ENDIF.
CALL FUNCTION 'DDIF_TABL_ACTIVATE'
EXPORTING
name = zcl_abapgit_persistence_db=>c_tabname
auth_chk = abap_false
IMPORTING
rc = lv_rc
EXCEPTIONS
not_found = 1
put_failure = 2
OTHERS = 3.
IF sy-subrc <> 0 OR lv_rc <> 0.
zcx_abapgit_exception=>raise( 'migrate, error from DDIF_TABL_ACTIVATE' ).
ENDIF.
ENDMETHOD.
METHOD table_exists.
DATA: lv_tabname TYPE dd02l-tabname.
SELECT SINGLE tabname FROM dd02l INTO lv_tabname
WHERE tabname = zcl_abapgit_persistence_db=>c_tabname.
rv_exists = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD update_global_settings.
DATA: li_ixml TYPE REF TO if_ixml,
lv_settings_xml TYPE string,
li_ostream TYPE REF TO if_ixml_ostream,
li_renderer TYPE REF TO if_ixml_renderer,
li_streamfactory TYPE REF TO if_ixml_stream_factory.
" finally update global settings
" migrated elements are already removed from document
li_ixml = cl_ixml=>create( ).
li_streamfactory = li_ixml->create_stream_factory( ).
li_ostream = li_streamfactory->create_ostream_cstring( lv_settings_xml ).
li_renderer = li_ixml->create_renderer( ostream = li_ostream
document = ii_document ).
li_renderer->render( ).
zcl_abapgit_persistence_db=>get_instance( )->update(
iv_type = zcl_abapgit_persistence_db=>c_type_settings
iv_value = ''
iv_data = lv_settings_xml ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PERSIST_INJECTOR IMPLEMENTATION.
METHOD set_repo.
zcl_abapgit_persist_factory=>gi_repo = ii_repo.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PERSIST_FACTORY IMPLEMENTATION.
METHOD get_repo.
IF gi_repo IS INITIAL.
CREATE OBJECT gi_repo TYPE zcl_abapgit_persistence_repo.
ENDIF.
ri_repo = gi_repo.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PERSIST_BACKGROUND IMPLEMENTATION.
METHOD constructor.
mo_db = zcl_abapgit_persistence_db=>get_instance( ).
ENDMETHOD.
METHOD delete.
TRY.
mo_db->read( iv_type = zcl_abapgit_persistence_db=>c_type_background
iv_value = iv_key ).
CATCH zcx_abapgit_not_found.
RETURN.
ENDTRY.
mo_db->delete( iv_type = zcl_abapgit_persistence_db=>c_type_background
iv_value = iv_key ).
DELETE mt_jobs WHERE key = iv_key.
ENDMETHOD.
METHOD exists.
list( ). " Ensure mt_jobs is populated
READ TABLE mt_jobs WITH KEY key = iv_key TRANSPORTING NO FIELDS.
rv_yes = boolc( sy-subrc = 0 ).
ENDMETHOD. "exists
METHOD from_xml.
CALL TRANSFORMATION id
OPTIONS value_handling = 'accept_data_loss'
SOURCE XML iv_string
RESULT data = rs_xml ##NO_TEXT.
ENDMETHOD.
METHOD list.
DATA: lt_list TYPE zif_abapgit_persistence=>tt_content,
ls_xml TYPE ty_xml.
FIELD-SYMBOLS: <ls_list> LIKE LINE OF lt_list,
<ls_output> LIKE LINE OF rt_list.
IF lines( mt_jobs ) > 0.
rt_list = mt_jobs.
RETURN.
ENDIF.
lt_list = mo_db->list_by_type( zcl_abapgit_persistence_db=>c_type_background ).
LOOP AT lt_list ASSIGNING <ls_list>.
ls_xml = from_xml( <ls_list>-data_str ).
APPEND INITIAL LINE TO rt_list ASSIGNING <ls_output>.
MOVE-CORRESPONDING ls_xml TO <ls_output>.
<ls_output>-key = <ls_list>-value.
ENDLOOP.
mt_jobs = rt_list.
ENDMETHOD.
METHOD modify.
ASSERT NOT is_data-key IS INITIAL.
mo_db->modify(
iv_type = zcl_abapgit_persistence_db=>c_type_background
iv_value = is_data-key
iv_data = to_xml( is_data ) ).
DELETE mt_jobs WHERE key = is_data-key.
APPEND is_data TO mt_jobs.
ENDMETHOD.
METHOD to_xml.
DATA: ls_xml TYPE ty_xml.
MOVE-CORRESPONDING is_background TO ls_xml.
CALL TRANSFORMATION id
SOURCE data = ls_xml
RESULT XML rv_string.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OO_SERIALIZER IMPLEMENTATION.
METHOD are_test_classes_skipped.
rv_return = mv_skip_testclass.
ENDMETHOD.
METHOD calculate_skip_testclass.
DATA: lv_line1 LIKE LINE OF it_source,
lv_line2 LIKE LINE OF it_source.
rv_skip_testclass = abap_false.
IF lines( it_source ) = 2.
READ TABLE it_source INDEX 1 INTO lv_line1.
ASSERT sy-subrc = 0.
READ TABLE it_source INDEX 2 INTO lv_line2.
ASSERT sy-subrc = 0.
IF strlen( lv_line1 ) >= 3 AND lv_line1(3) = '*"*' AND lv_line2 IS INITIAL.
rv_skip_testclass = abap_true.
ENDIF.
ELSEIF lines( it_source ) = 1.
READ TABLE it_source INDEX 1 INTO lv_line1.
ASSERT sy-subrc = 0.
IF lv_line1 IS INITIAL
OR ( strlen( lv_line1 ) >= 3 AND lv_line1(3) = '*"*' )
OR ( strlen( lv_line1 ) = 1 AND lv_line1(1) = '*' ).
rv_skip_testclass = abap_true.
ENDIF.
ELSEIF lines( it_source ) = 0.
rv_skip_testclass = abap_true.
ENDIF.
ENDMETHOD.
METHOD read_include.
DATA: ls_include TYPE progstruc.
ASSERT iv_type = seop_ext_class_locals_def
OR iv_type = seop_ext_class_locals_imp
OR iv_type = seop_ext_class_macros
OR iv_type = seop_ext_class_testclasses.
ls_include-rootname = is_clskey-clsname.
TRANSLATE ls_include-rootname USING ' ='.
ls_include-categorya = iv_type(1).
ls_include-codea = iv_type+1(4).
READ REPORT ls_include INTO rt_source STATE 'A'.
ENDMETHOD.
METHOD reduce.
DATA: lv_source LIKE LINE OF ct_source,
lv_found TYPE sap_bool.
lv_found = abap_false.
LOOP AT ct_source INTO lv_source.
IF strlen( lv_source ) >= 3 AND lv_source(3) <> '*"*'.
lv_found = abap_true.
ENDIF.
ENDLOOP.
IF lv_found = abap_false.
CLEAR ct_source.
ENDIF.
ENDMETHOD.
METHOD remove_signatures.
DATA: lv_begin TYPE string,
lv_end TYPE string,
lv_remove TYPE sap_bool,
lv_source LIKE LINE OF ct_source.
"@TODO: Put under test
CONCATENATE '* <SIGNATURE>------------------------------------'
'---------------------------------------------------+'
INTO lv_begin.
CONCATENATE '* +------------------------------------------------'
'--------------------------------------</SIGNATURE>'
INTO lv_end.
lv_remove = abap_false.
LOOP AT ct_source INTO lv_source.
IF lv_source = lv_begin.
lv_remove = abap_true.
ENDIF.
IF lv_remove = abap_true.
DELETE ct_source INDEX sy-tabix.
ENDIF.
IF lv_source = lv_end.
lv_remove = abap_false.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD serialize_abap_clif_source.
TRY.
rt_source = serialize_abap_new( is_class_key ).
CATCH cx_sy_dyn_call_error.
rt_source = serialize_abap_old( is_class_key ).
ENDTRY.
ENDMETHOD.
METHOD serialize_abap_new.
DATA: lo_source TYPE REF TO object,
lo_instance TYPE REF TO object.
CALL METHOD ('CL_OO_FACTORY')=>('CREATE_INSTANCE')
RECEIVING
result = lo_instance.
CALL METHOD lo_instance->('CREATE_CLIF_SOURCE')
EXPORTING
clif_name = is_clskey-clsname
version = 'A'
RECEIVING
result = lo_source.
CALL METHOD lo_source->('GET_SOURCE')
IMPORTING
source = rt_source.
ENDMETHOD.
METHOD serialize_abap_old.
DATA: lo_source TYPE REF TO cl_oo_source.
CREATE OBJECT lo_source
EXPORTING
clskey = is_clskey
EXCEPTIONS
class_not_existing = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from CL_OO_SOURCE' ).
ENDIF.
lo_source->read( 'A' ).
rt_source = lo_source->get_old_source( ).
remove_signatures( CHANGING ct_source = rt_source ).
ENDMETHOD.
METHOD serialize_locals_def.
rt_source = read_include( is_clskey = is_clskey
iv_type = seop_ext_class_locals_def ).
reduce( CHANGING ct_source = rt_source ).
ENDMETHOD.
METHOD serialize_locals_imp.
rt_source = read_include( is_clskey = is_clskey
iv_type = seop_ext_class_locals_imp ).
reduce( CHANGING ct_source = rt_source ).
ENDMETHOD.
METHOD serialize_macros.
rt_source = read_include( is_clskey = is_clskey
iv_type = seop_ext_class_macros ).
reduce( CHANGING ct_source = rt_source ).
ENDMETHOD.
METHOD serialize_testclasses.
rt_source = read_include( is_clskey = is_clskey
iv_type = seop_ext_class_testclasses ).
mv_skip_testclass = calculate_skip_testclass( rt_source ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_oo_interface IMPLEMENTATION.
METHOD zif_abapgit_oo_object_fnc~create.
CALL FUNCTION 'SEO_INTERFACE_CREATE_COMPLETE'
EXPORTING
devclass = iv_package
overwrite = iv_overwrite
CHANGING
interface = cg_properties
EXCEPTIONS
existing = 1
is_class = 2
db_error = 3
component_error = 4
no_access = 5
other = 6
OTHERS = 7.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from SEO_INTERFACE_CREATE_COMPLETE' ).
ENDIF.
ENDMETHOD.
include zif_abapgit_oo_object_fnc~get_includes.
DATA lv_interface_name TYPE seoclsname.
lv_interface_name = iv_object_name.
APPEND cl_oo_classname_service=>get_interfacepool_name( lv_interface_name ) TO rt_includes.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~get_interface_properties.
CALL FUNCTION 'SEO_CLIF_GET'
EXPORTING
cifkey = is_interface_key
version = seoc_version_active
IMPORTING
interface = rs_interface_properties
EXCEPTIONS
not_existing = 1
deleted = 2
model_only = 3
OTHERS = 4.
IF sy-subrc = 1.
RETURN. " in case only inactive version exists
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from seo_clif_get' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~delete.
CALL FUNCTION 'SEO_INTERFACE_DELETE_COMPLETE'
EXPORTING
intkey = is_deletion_key
EXCEPTIONS
not_existing = 1
is_class = 2
db_error = 3
no_access = 4
other = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from SEO_INTERFACE_DELETE_COMPLETE' ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OO_FACTORY IMPLEMENTATION.
METHOD make.
IF gi_object_oriented_object IS BOUND.
ro_object_oriented_object = gi_object_oriented_object.
RETURN.
ENDIF.
IF iv_object_type = 'CLAS'.
CREATE OBJECT ro_object_oriented_object TYPE zcl_abapgit_oo_class.
ELSEIF iv_object_type = 'INTF'.
CREATE OBJECT ro_object_oriented_object TYPE zcl_abapgit_oo_interface.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OO_CLASS_NEW IMPLEMENTATION.
METHOD create_report.
INSERT REPORT iv_program FROM it_source EXTENSION TYPE iv_extension STATE iv_version PROGRAM TYPE iv_program_type.
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD determine_method_include.
DATA: ls_mtdkey TYPE seocpdkey.
ls_mtdkey-clsname = iv_name.
ls_mtdkey-cpdname = iv_method.
cl_oo_classname_service=>get_method_include(
EXPORTING
mtdkey = ls_mtdkey
RECEIVING
result = rv_program
EXCEPTIONS
method_not_existing = 1 ).
IF sy-subrc = 0.
RETURN.
ENDIF.
CALL FUNCTION 'SEO_METHOD_GENERATE_INCLUDE'
EXPORTING
suppress_mtdkey_check = seox_true
mtdkey = ls_mtdkey
EXCEPTIONS
not_existing = 1
model_only = 2
include_existing = 3
method_imp_not_generated = 4
method_imp_not_initialised = 5
_internal_class_not_existing = 6
_internal_method_overflow = 7
cancelled = 8
method_is_abstract_implemented = 9
method_is_final_implemented = 10
internal_error_insert_report = 11
OTHERS = 12.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SEO_METHOD_GENERATE_INCLUDE' ).
ENDIF.
rv_program = cl_oo_classname_service=>get_method_include( ls_mtdkey ).
ENDMETHOD.
METHOD generate_classpool.
DATA: ls_clskey TYPE seoclskey.
ls_clskey-clsname = iv_name.
CALL FUNCTION 'SEO_CLASS_GENERATE_CLASSPOOL'
EXPORTING
clskey = ls_clskey
suppress_corr = seox_true
EXCEPTIONS
not_existing = 1
model_only = 2
class_pool_not_generated = 3
class_stment_not_generated = 4
locals_not_generated = 5
macros_not_generated = 6
public_sec_not_generated = 7
protected_sec_not_generated = 8
private_sec_not_generated = 9
typeref_not_generated = 10
class_pool_not_initialised = 11
class_stment_not_initialised = 12
locals_not_initialised = 13
macros_not_initialised = 14
public_sec_not_initialised = 15
protected_sec_not_initialised = 16
private_sec_not_initialised = 17
typeref_not_initialised = 18
_internal_class_overflow = 19
OTHERS = 20.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SEO_CLASS_GENERATE_CLASSPOOL' ).
ENDIF.
ENDMETHOD.
METHOD init_scanner.
TRY.
ro_scanner = cl_oo_source_scanner_class=>create_class_scanner(
clif_name = iv_name
source = it_source ).
ro_scanner->scan( ).
CATCH cx_clif_scan_error.
zcx_abapgit_exception=>raise( 'error initializing CLAS scanner' ).
ENDTRY.
ENDMETHOD.
METHOD update_cs_number_of_methods.
" Indirect access to keep downward compatibility
DATA lr_cache_entry TYPE REF TO data.
FIELD-SYMBOLS: <lg_cache_entry> TYPE any,
<lg_field> TYPE any.
TRY.
CREATE DATA lr_cache_entry TYPE ('SEO_CS_CACHE').
CATCH cx_sy_create_data_error.
RETURN.
ENDTRY.
ASSIGN lr_cache_entry->* TO <lg_cache_entry>.
ASSERT sy-subrc = 0.
ASSIGN COMPONENT 'CLSNAME' OF STRUCTURE <lg_cache_entry>
TO <lg_field>.
ASSERT sy-subrc = 0.
<lg_field> = iv_classname.
ASSIGN COMPONENT 'NO_OF_METHOD_IMPLS' OF STRUCTURE <lg_cache_entry>
TO <lg_field>.
ASSERT sy-subrc = 0.
<lg_field> = iv_number_of_impl_methods.
MODIFY ('SEO_CS_CACHE') FROM <lg_cache_entry>.
ENDMETHOD.
METHOD update_full_class_include.
CONSTANTS: lc_class_source_extension TYPE sychar02 VALUE 'CS',
lc_include_program_type TYPE sychar01 VALUE 'I',
lc_active_version TYPE r3state VALUE 'A'.
create_report( iv_program = cl_oo_classname_service=>get_cs_name( iv_classname )
it_source = it_source
iv_extension = lc_class_source_extension
iv_program_type = lc_include_program_type
iv_version = lc_active_version ).
" Assuming that all methods that were scanned are implemented
update_cs_number_of_methods( iv_classname = iv_classname
iv_number_of_impl_methods = lines( it_methods ) ).
ENDMETHOD.
METHOD update_meta.
DATA: lo_update TYPE REF TO cl_oo_class_section_source,
ls_clskey TYPE seoclskey,
lv_scan_error TYPE seox_boolean.
ls_clskey-clsname = iv_name.
TRY.
CREATE OBJECT lo_update TYPE ('CL_OO_CLASS_SECTION_SOURCE')
EXPORTING
clskey = ls_clskey
exposure = iv_exposure
state = 'A'
source = it_source
suppress_constrctr_generation = seox_true
EXCEPTIONS
class_not_existing = 1
read_source_error = 2
OTHERS = 3.
CATCH cx_sy_dyn_call_param_not_found.
CREATE OBJECT lo_update TYPE cl_oo_class_section_source
EXPORTING
clskey = ls_clskey
exposure = iv_exposure
state = 'A'
EXCEPTIONS
class_not_existing = 1
read_source_error = 2
OTHERS = 3.
ENDTRY.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error instantiating CL_OO_CLASS_SECTION_SOURCE' ).
ENDIF.
lo_update->set_dark_mode( seox_true ).
TRY.
CALL METHOD lo_update->('SET_AMDP_SUPPORT')
EXPORTING
enabled = abap_true.
CATCH cx_sy_dyn_call_illegal_method.
ENDTRY.
lo_update->scan_section_source(
RECEIVING
scan_error = lv_scan_error
EXCEPTIONS
scan_abap_source_error = 1
OTHERS = 2 ).
IF sy-subrc <> 0 OR lv_scan_error = abap_true.
zcx_abapgit_exception=>raise( 'CLAS, error while scanning source' ).
ENDIF.
lo_update->revert_scan_result( ).
IF iv_exposure = seoc_exposure_public.
generate_classpool( iv_name ).
ENDIF.
ENDMETHOD.
METHOD update_report.
DATA: lt_old TYPE string_table.
READ REPORT iv_program INTO lt_old.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Fatal error. Include { iv_program } should have been created previously!| ).
ENDIF.
IF lt_old <> it_source.
INSERT REPORT iv_program FROM it_source.
ASSERT sy-subrc = 0.
rv_updated = abap_true.
ELSE.
rv_updated = abap_false.
ENDIF.
ENDMETHOD.
METHOD update_source_index.
CONSTANTS:
lc_version_active TYPE r3state VALUE 'A', "#EC NOTEXT
lc_version_inactive TYPE r3state VALUE 'I'. "#EC NOTEXT
" dynamic invocation, IF_OO_SOURCE_POS_INDEX_HELPER doesn't exist in 702.
DATA lo_index_helper TYPE REF TO object.
TRY.
CREATE OBJECT lo_index_helper TYPE ('CL_OO_SOURCE_POS_INDEX_HELPER').
CALL METHOD lo_index_helper->('IF_OO_SOURCE_POS_INDEX_HELPER~CREATE_INDEX_WITH_SCANNER')
EXPORTING
class_name = iv_clsname
version = lc_version_active
scanner = io_scanner.
CALL METHOD lo_index_helper->('IF_OO_SOURCE_POS_INDEX_HELPER~DELETE_INDEX')
EXPORTING
class_name = iv_clsname
version = lc_version_inactive.
CATCH cx_root.
" it's probably okay to no update the index
RETURN.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~create.
CALL FUNCTION 'SEO_CLASS_CREATE_COMPLETE'
EXPORTING
devclass = iv_package
overwrite = iv_overwrite
version = seoc_version_active
CHANGING
class = cg_properties
EXCEPTIONS
existing = 1
is_interface = 2
db_error = 3
component_error = 4
no_access = 5
other = 6
OTHERS = 7.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SEO_CLASS_CREATE_COMPLETE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~deserialize_source.
DATA: lv_updated TYPE abap_bool,
lv_program TYPE program,
lo_scanner TYPE REF TO cl_oo_source_scanner_class,
lt_methods TYPE cl_oo_source_scanner_class=>type_method_implementations,
lv_method LIKE LINE OF lt_methods,
lt_source TYPE seop_source_string.
"Buffer needs to be refreshed,
"otherwise standard SAP CLIF_SOURCE reorder methods alphabetically
CALL FUNCTION 'SEO_BUFFER_INIT'.
CALL FUNCTION 'SEO_BUFFER_REFRESH'
EXPORTING
cifkey = is_key
version = seoc_version_inactive.
lo_scanner = init_scanner(
it_source = it_source
iv_name = is_key-clsname ).
lt_source = lo_scanner->get_public_section_source( ).
lv_program = cl_oo_classname_service=>get_pubsec_name( is_key-clsname ).
lv_updated = update_report( iv_program = lv_program
it_source = lt_source ).
IF lv_updated = abap_true.
update_meta( iv_name = is_key-clsname
iv_exposure = seoc_exposure_public
it_source = lt_source ).
ENDIF.
lt_source = lo_scanner->get_protected_section_source( ).
lv_program = cl_oo_classname_service=>get_prosec_name( is_key-clsname ).
lv_updated = update_report( iv_program = lv_program
it_source = lt_source ).
IF lv_updated = abap_true.
update_meta( iv_name = is_key-clsname
iv_exposure = seoc_exposure_protected
it_source = lt_source ).
ENDIF.
lt_source = lo_scanner->get_private_section_source( ).
lv_program = cl_oo_classname_service=>get_prisec_name( is_key-clsname ).
lv_updated = update_report( iv_program = lv_program
it_source = lt_source ).
IF lv_updated = abap_true.
update_meta( iv_name = is_key-clsname
iv_exposure = seoc_exposure_private
it_source = lt_source ).
ENDIF.
lt_methods = lo_scanner->get_method_implementations( ).
LOOP AT lt_methods INTO lv_method.
TRY.
lt_source = lo_scanner->get_method_impl_source( lv_method ).
CATCH cx_oo_clif_component.
zcx_abapgit_exception=>raise( 'error from GET_METHOD_IMPL_SOURCE' ).
ENDTRY.
lv_program = determine_method_include(
iv_name = is_key-clsname
iv_method = lv_method ).
update_report(
iv_program = lv_program
it_source = lt_source ).
ENDLOOP.
update_full_class_include( iv_classname = is_key-clsname
it_source = it_source
it_methods = lt_methods ).
update_source_index(
iv_clsname = is_key-clsname
io_scanner = lo_scanner ).
zcl_abapgit_objects_activation=>add(
iv_type = 'CLAS'
iv_name = is_key-clsname ).
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~generate_locals.
DATA: lv_program TYPE programm.
lv_program = cl_oo_classname_service=>get_ccdef_name( is_key-clsname ).
update_report( iv_program = lv_program
it_source = it_local_definitions ).
lv_program = cl_oo_classname_service=>get_ccimp_name( is_key-clsname ).
update_report( iv_program = lv_program
it_source = it_local_implementations ).
lv_program = cl_oo_classname_service=>get_ccmac_name( is_key-clsname ).
update_report( iv_program = lv_program
it_source = it_local_macros ).
IF lines( it_local_test_classes ) > 0.
lv_program = cl_oo_classname_service=>get_ccau_name( is_key-clsname ).
update_report( iv_program = lv_program
it_source = it_local_test_classes ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_oo_class IMPLEMENTATION.
METHOD zif_abapgit_oo_object_fnc~create.
CALL FUNCTION 'SEO_CLASS_CREATE_COMPLETE'
EXPORTING
devclass = iv_package
overwrite = iv_overwrite
CHANGING
class = cg_properties
EXCEPTIONS
existing = 1
is_interface = 2
db_error = 3
component_error = 4
no_access = 5
other = 6
OTHERS = 7.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SEO_CLASS_CREATE_COMPLETE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~generate_locals.
CALL FUNCTION 'SEO_CLASS_GENERATE_LOCALS'
EXPORTING
clskey = is_key
force = iv_force
locals_def = it_local_definitions
locals_imp = it_local_implementations
locals_mac = it_local_macros
locals_testclasses = it_local_test_classes
EXCEPTIONS
not_existing = 1
model_only = 2
locals_not_generated = 3
locals_not_initialised = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from generate_locals' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~insert_text_pool.
DATA: lv_cp TYPE program.
lv_cp = cl_oo_classname_service=>get_classpool_name( iv_class_name ).
INSERT TEXTPOOL lv_cp
FROM it_text_pool
LANGUAGE iv_language
STATE 'I'.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from INSERT TEXTPOOL' ).
ENDIF.
zcl_abapgit_objects_activation=>add( iv_type = 'REPT'
iv_name = lv_cp ).
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~create_sotr.
DATA: lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt,
lt_objects TYPE sotr_objects,
ls_paket TYPE sotr_pack,
lv_object LIKE LINE OF lt_objects.
FIELD-SYMBOLS: <ls_sotr> LIKE LINE OF lt_sotr.
LOOP AT it_sotr ASSIGNING <ls_sotr>.
CALL FUNCTION 'SOTR_OBJECT_GET_OBJECTS'
EXPORTING
object_vector = <ls_sotr>-header-objid_vec
IMPORTING
objects = lt_objects
EXCEPTIONS
object_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SOTR_OBJECT_GET_OBJECTS' ).
ENDIF.
READ TABLE lt_objects INDEX 1 INTO lv_object.
ASSERT sy-subrc = 0.
ls_paket-paket = iv_package.
CALL FUNCTION 'SOTR_CREATE_CONCEPT'
EXPORTING
paket = ls_paket
crea_lan = <ls_sotr>-header-crea_lan
alias_name = <ls_sotr>-header-alias_name
object = lv_object
entries = <ls_sotr>-entries
concept_default = <ls_sotr>-header-concept
EXCEPTIONS
package_missing = 1
crea_lan_missing = 2
object_missing = 3
paket_does_not_exist = 4
alias_already_exist = 5
object_type_not_found = 6
langu_missing = 7
identical_context_not_allowed = 8
text_too_long = 9
error_in_update = 10
no_master_langu = 11
error_in_concept_id = 12
alias_not_allowed = 13
tadir_entry_creation_failed = 14
internal_error = 15
error_in_correction = 16
user_cancelled = 17
no_entry_found = 18
OTHERS = 19.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SOTR_CREATE_CONCEPT' ).
ENDIF.
ENDLOOP.
ENDMETHOD.
include zif_abapgit_oo_object_fnc~get_includes.
DATA: lv_class_name TYPE seoclsname,
lt_methods TYPE seop_methods_w_include.
FIELD-SYMBOLS: <ls_method> LIKE LINE OF lt_methods.
lv_class_name = iv_object_name.
APPEND cl_oo_classname_service=>get_ccdef_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_ccmac_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_ccimp_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_cl_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_ccau_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_pubsec_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_prosec_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_prisec_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_classpool_name( lv_class_name ) TO rt_includes.
APPEND cl_oo_classname_service=>get_ct_name( lv_class_name ) TO rt_includes.
cl_oo_classname_service=>get_all_method_includes(
EXPORTING
clsname = lv_class_name
RECEIVING
result = lt_methods
EXCEPTIONS
class_not_existing = 1 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Class { lv_class_name } not existing| ).
ENDIF.
LOOP AT lt_methods ASSIGNING <ls_method>.
APPEND <ls_method>-incname TO rt_includes.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~get_class_properties.
CALL FUNCTION 'SEO_CLIF_GET'
EXPORTING
cifkey = is_class_key
version = seoc_version_active
IMPORTING
class = rs_class_properties
EXCEPTIONS
not_existing = 1
deleted = 2
model_only = 3
OTHERS = 4.
IF sy-subrc = 1.
RETURN. " in case only inactive version exists
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from seo_clif_get' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~read_text_pool.
DATA:
lv_cp TYPE program.
lv_cp = cl_oo_classname_service=>get_classpool_name( iv_class_name ).
READ TEXTPOOL lv_cp INTO rt_text_pool LANGUAGE iv_language. "#EC CI_READ_REP
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~read_sotr.
DATA: lv_concept TYPE sotr_head-concept,
lt_seocompodf TYPE STANDARD TABLE OF seocompodf WITH DEFAULT KEY,
ls_header TYPE sotr_head,
lt_entries TYPE sotr_text_tt.
FIELD-SYMBOLS: <ls_sotr> LIKE LINE OF rt_sotr,
<ls_seocompodf> LIKE LINE OF lt_seocompodf,
<ls_entry> LIKE LINE OF lt_entries.
SELECT * FROM seocompodf
INTO TABLE lt_seocompodf
WHERE clsname = iv_object_name
AND version = '1'
AND exposure = '2'
AND attdecltyp = '2'
AND type = 'SOTR_CONC'
ORDER BY PRIMARY KEY. "#EC CI_SUBRC
LOOP AT lt_seocompodf ASSIGNING <ls_seocompodf>.
lv_concept = translate( val = <ls_seocompodf>-attvalue from = '''' to = '' ).
CALL FUNCTION 'SOTR_GET_CONCEPT'
EXPORTING
concept = lv_concept
IMPORTING
header = ls_header
TABLES
entries = lt_entries
EXCEPTIONS
no_entry_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
CONTINUE.
ENDIF.
CLEAR: ls_header-paket,
ls_header-crea_name,
ls_header-crea_tstut,
ls_header-chan_name,
ls_header-chan_tstut.
LOOP AT lt_entries ASSIGNING <ls_entry>.
CLEAR: <ls_entry>-version,
<ls_entry>-crea_name,
<ls_entry>-crea_tstut,
<ls_entry>-chan_name,
<ls_entry>-chan_tstut.
ENDLOOP.
APPEND INITIAL LINE TO rt_sotr ASSIGNING <ls_sotr>.
<ls_sotr>-header = ls_header.
<ls_sotr>-entries = lt_entries.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~delete.
CALL FUNCTION 'SEO_CLASS_DELETE_COMPLETE'
EXPORTING
clskey = is_deletion_key
EXCEPTIONS
not_existing = 1
is_interface = 2
db_error = 3
no_access = 4
other = 5
OTHERS = 6.
IF sy-subrc = 1.
RETURN.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from SEO_CLASS_DELETE_COMPLETE: { sy-subrc }| ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OO_BASE IMPLEMENTATION.
METHOD deserialize_abap_source_new.
DATA: lo_factory TYPE REF TO object,
lo_source TYPE REF TO object,
lo_settings TYPE REF TO object,
lr_settings TYPE REF TO data.
FIELD-SYMBOLS <lg_settings> TYPE any.
"Buffer needs to be refreshed,
"otherwise standard SAP CLIF_SOURCE reorder methods alphabetically
CALL FUNCTION 'SEO_BUFFER_INIT'.
CALL FUNCTION 'SEO_BUFFER_REFRESH'
EXPORTING
cifkey = is_clskey
version = seoc_version_inactive.
CALL METHOD ('CL_OO_FACTORY')=>('CREATE_INSTANCE')
RECEIVING
result = lo_factory.
"Enable modification mode to avoid exception CX_OO_ACCESS_PERMISSON when
"dealing with objects in foreign namespaces (namespace role = C)
CALL METHOD lo_factory->('CREATE_SETTINGS')
EXPORTING
modification_mode_enabled = abap_true
RECEIVING
result = lo_settings.
CREATE DATA lr_settings TYPE REF TO ('IF_OO_CLIF_SOURCE_SETTINGS').
ASSIGN lr_settings->* TO <lg_settings>.
<lg_settings> ?= lo_settings.
CALL METHOD lo_factory->('CREATE_CLIF_SOURCE')
EXPORTING
clif_name = is_clskey-clsname
settings = <lg_settings>
RECEIVING
result = lo_source.
TRY.
CALL METHOD lo_source->('IF_OO_CLIF_SOURCE~LOCK').
CATCH cx_oo_access_permission.
zcx_abapgit_exception=>raise( 'source_new, access permission exception' ).
ENDTRY.
CALL METHOD lo_source->('IF_OO_CLIF_SOURCE~SET_SOURCE')
EXPORTING
source = it_source.
CALL METHOD lo_source->('IF_OO_CLIF_SOURCE~SAVE').
CALL METHOD lo_source->('IF_OO_CLIF_SOURCE~UNLOCK').
ENDMETHOD.
METHOD deserialize_abap_source_old.
"for backwards compatability down to 702
DATA: lo_source TYPE REF TO cl_oo_source.
CREATE OBJECT lo_source
EXPORTING
clskey = is_clskey
EXCEPTIONS
class_not_existing = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from CL_OO_SOURCE' ).
ENDIF.
TRY.
lo_source->access_permission( seok_access_modify ).
lo_source->set_source( it_source ).
lo_source->save( ).
lo_source->access_permission( seok_access_free ).
CATCH cx_oo_access_permission.
zcx_abapgit_exception=>raise( 'permission error' ).
CATCH cx_oo_source_save_failure.
zcx_abapgit_exception=>raise( 'save failure' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~add_to_activation_list.
zcl_abapgit_objects_activation=>add_item( is_item ).
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~create.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~create_documentation.
CALL FUNCTION 'DOCU_UPD'
EXPORTING
id = 'CL'
langu = iv_language
object = iv_object_name
TABLES
line = it_lines
EXCEPTIONS
ret_code = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DOCU_UPD' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~create_sotr.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~delete.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~deserialize_source.
TRY.
deserialize_abap_source_new(
is_clskey = is_key
it_source = it_source ).
CATCH cx_sy_dyn_call_error.
deserialize_abap_source_old(
is_clskey = is_key
it_source = it_source ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~exists.
CALL FUNCTION 'SEO_CLASS_EXISTENCE_CHECK'
EXPORTING
clskey = is_object_name
EXCEPTIONS
not_specified = 1
not_existing = 2
is_interface = 3
no_text = 4
inconsistent = 5
OTHERS = 6.
rv_exists = boolc( sy-subrc <> 2 ).
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~generate_locals.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~get_class_properties.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
include zif_abapgit_oo_object_fnc~get_includes.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~get_interface_properties.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~get_skip_test_classes.
rv_skip = mv_skip_test_classes.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~insert_text_pool.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~read_descriptions.
SELECT * FROM seocompotx INTO TABLE rt_descriptions
WHERE clsname = iv_obejct_name
AND descript <> ''
ORDER BY PRIMARY KEY. "#EC CI_SUBRC
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~read_documentation.
DATA: lv_state TYPE dokstate,
lv_object TYPE dokhl-object,
lt_lines TYPE tlinetab.
lv_object = iv_class_name.
CALL FUNCTION 'DOCU_GET'
EXPORTING
id = 'CL'
langu = iv_language
object = lv_object
IMPORTING
dokstate = lv_state
TABLES
line = lt_lines
EXCEPTIONS
no_docu_on_screen = 1
no_docu_self_def = 2
no_docu_temp = 3
ret_code = 4
OTHERS = 5.
IF sy-subrc = 0 AND lv_state = 'R'.
rt_lines = lt_lines.
ELSE.
CLEAR rt_lines.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~read_sotr.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~read_superclass.
SELECT SINGLE refclsname FROM vseoextend INTO rv_superclass
WHERE clsname = iv_classname.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~read_text_pool.
ASSERT 0 = 1. "Subclass responsibility
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~serialize_abap.
DATA lo_oo_serializer TYPE REF TO zcl_abapgit_oo_serializer.
CREATE OBJECT lo_oo_serializer.
CASE iv_type.
WHEN seop_ext_class_locals_def.
rt_source = lo_oo_serializer->serialize_locals_def( is_class_key ).
WHEN seop_ext_class_locals_imp.
rt_source = lo_oo_serializer->serialize_locals_imp( is_class_key ).
WHEN seop_ext_class_macros.
rt_source = lo_oo_serializer->serialize_macros( is_class_key ).
WHEN seop_ext_class_testclasses.
rt_source = lo_oo_serializer->serialize_testclasses( is_class_key ).
mv_skip_test_classes = lo_oo_serializer->are_test_classes_skipped( ).
WHEN OTHERS.
rt_source = lo_oo_serializer->serialize_abap_clif_source( is_class_key ).
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_oo_object_fnc~update_descriptions.
DELETE FROM seocompotx WHERE clsname = is_key-clsname. "#EC CI_SUBRC
INSERT seocompotx FROM TABLE it_descriptions. "#EC CI_SUBRC
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_objects_super IMPLEMENTATION.
METHOD set_default_package.
" In certain cases we need to set the package package via ABAP memory
" because we can't supply it via the APIs.
"
" Set default package, see function module RS_CORR_INSERT FORM get_current_devclass.
"
" We use ABAP memory instead the SET parameter because it is
" more reliable. SET parameter doesn't work when multiple objects
" are deserialized which uses the ABAP memory mechanism.
" We don't need to reset the memory as it is done in above mentioned form routine.
EXPORT current_devclass FROM iv_package TO MEMORY ID 'EUK'.
ENDMETHOD.
METHOD check_timestamp.
DATA: lv_ts TYPE timestamp.
IF sy-subrc = 0 AND iv_date IS NOT INITIAL AND iv_time IS NOT INITIAL.
cl_abap_tstmp=>systemtstmp_syst2utc(
EXPORTING syst_date = iv_date
syst_time = iv_time
IMPORTING utc_tstmp = lv_ts ).
IF lv_ts < iv_timestamp.
rv_changed = abap_false. " Unchanged
ELSE.
rv_changed = abap_true.
ENDIF.
ELSE. " Not found? => changed
rv_changed = abap_true.
ENDIF.
ENDMETHOD.
METHOD constructor.
ms_item = is_item.
ASSERT NOT ms_item IS INITIAL.
mv_language = iv_language.
ASSERT NOT mv_language IS INITIAL.
ENDMETHOD.
METHOD corr_insert.
DATA: ls_object TYPE ddenqs.
ls_object-objtype = ms_item-obj_type.
ls_object-objname = ms_item-obj_name.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = ls_object
object_class = 'DICT'
devclass = iv_package
master_language = mv_language
mode = 'INSERT'
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc = 1.
zcx_abapgit_exception=>raise( 'Cancelled' ).
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT' ).
ENDIF.
ENDMETHOD.
METHOD exists_a_lock_entry_for.
DATA: lt_lock_entries TYPE STANDARD TABLE OF seqg3.
CALL FUNCTION 'ENQUEUE_READ'
EXPORTING
guname = '*'
garg = iv_argument
TABLES
enq = lt_lock_entries
EXCEPTIONS
communication_failure = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
READ TABLE lt_lock_entries TRANSPORTING NO FIELDS
WITH KEY gobj = iv_lock_object.
IF sy-subrc = 0.
rv_exists_a_lock_entry = abap_true.
ENDIF.
ENDMETHOD.
METHOD get_metadata.
DATA: lv_class TYPE string.
lv_class = cl_abap_classdescr=>describe_by_object_ref( me )->get_relative_name( ).
REPLACE FIRST OCCURRENCE OF 'ZCL_ABAPGIT' IN lv_class WITH 'LCL'.
rs_metadata-class = lv_class.
rs_metadata-version = 'v1.0.0' ##no_text.
ENDMETHOD.
METHOD is_adt_jump_possible.
DATA: lo_wb_request TYPE REF TO cl_wb_request,
lo_adt_uri_mapper_vit TYPE REF TO object,
lv_vit_wb_request TYPE abap_bool.
cl_wb_request=>create_from_object_ref(
EXPORTING
p_wb_object = io_object
RECEIVING
p_wb_request = lo_wb_request
EXCEPTIONS
illegal_operation = 1
cancelled = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'ADT Jump Error' ).
ENDIF.
TRY.
CALL METHOD io_adt->('IF_ADT_TOOLS_CORE_FACTORY~GET_URI_MAPPER_VIT')
RECEIVING
result = lo_adt_uri_mapper_vit.
CALL METHOD lo_adt_uri_mapper_vit->('IF_ADT_URI_MAPPER_VIT~IS_VIT_WB_REQUEST')
EXPORTING
wb_request = lo_wb_request
RECEIVING
result = lv_vit_wb_request.
IF lv_vit_wb_request = abap_true.
r_is_adt_jump_possible = abap_false.
ELSE.
r_is_adt_jump_possible = abap_true.
ENDIF.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'ADT Jump Error' ).
ENDTRY.
ENDMETHOD.
METHOD jump_adt.
DATA: lv_adt_link TYPE string,
lv_obj_type TYPE trobjtype,
lv_obj_name TYPE trobj_name,
lo_object TYPE REF TO cl_wb_object,
lo_adt TYPE REF TO object,
lo_adt_uri_mapper TYPE REF TO object,
lo_adt_objref TYPE REF TO object ##needed.
FIELD-SYMBOLS: <lv_uri> TYPE string.
lv_obj_name = i_obj_name.
lv_obj_type = i_obj_type.
TRY.
cl_wb_object=>create_from_transport_key(
EXPORTING
p_object = lv_obj_type
p_obj_name = lv_obj_name
RECEIVING
p_wb_object = lo_object
EXCEPTIONS
OTHERS = 1 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'ADT Jump Error' ).
ENDIF.
CALL METHOD ('CL_ADT_TOOLS_CORE_FACTORY')=>('GET_INSTANCE')
RECEIVING
result = lo_adt.
IF is_adt_jump_possible( io_object = lo_object
io_adt = lo_adt ) = abap_false.
zcx_abapgit_exception=>raise( 'ADT Jump Error' ).
ENDIF.
CALL METHOD lo_adt->('IF_ADT_TOOLS_CORE_FACTORY~GET_URI_MAPPER')
RECEIVING
result = lo_adt_uri_mapper.
CALL METHOD lo_adt_uri_mapper->('IF_ADT_URI_MAPPER~MAP_WB_OBJECT_TO_OBJREF')
EXPORTING
wb_object = lo_object
RECEIVING
result = lo_adt_objref.
ASSIGN ('LO_ADT_OBJREF->REF_DATA-URI') TO <lv_uri>.
ASSERT sy-subrc = 0.
CONCATENATE 'adt://' sy-sysid <lv_uri> INTO lv_adt_link.
cl_gui_frontend_services=>execute( EXPORTING document = lv_adt_link
EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'ADT Jump Error' ).
ENDIF.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'ADT Jump Error' ).
ENDTRY.
ENDMETHOD.
METHOD jump_se11.
DATA: lt_bdcdata TYPE TABLE OF bdcdata.
FIELD-SYMBOLS: <ls_bdcdata> LIKE LINE OF lt_bdcdata.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-program = 'SAPLSD_ENTRY'.
<ls_bdcdata>-dynpro = '1000'.
<ls_bdcdata>-dynbegin = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BDC_OKCODE'.
<ls_bdcdata>-fval = '=WB_DISPLAY'.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = iv_radio.
<ls_bdcdata>-fval = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = iv_field.
<ls_bdcdata>-fval = ms_item-obj_name.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SE11'
mode_val = 'E'
TABLES
using_tab = lt_bdcdata
EXCEPTIONS
system_failure = 1
communication_failure = 2
resource_failure = 3
OTHERS = 4
##fm_subrc_ok. "#EC CI_SUBRC
ENDMETHOD.
METHOD tadir_insert.
CALL FUNCTION 'TR_TADIR_INTERFACE'
EXPORTING
wi_test_modus = abap_false
wi_tadir_pgmid = 'R3TR'
wi_tadir_object = ms_item-obj_type
wi_tadir_obj_name = ms_item-obj_name
wi_tadir_author = sy-uname
wi_tadir_devclass = iv_package
wi_tadir_masterlang = mv_language
iv_delflag = abap_false
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from TR_TADIR_INTERFACE' ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_objects_saxx_super IMPLEMENTATION.
METHOD create_channel_objects.
get_names( ).
TRY.
IF mo_appl_obj_data IS NOT BOUND.
CREATE OBJECT mo_appl_obj_data TYPE (mv_appl_obj_cls_name).
ENDIF.
IF mo_persistence IS NOT BOUND.
CREATE OBJECT mo_persistence TYPE (mv_persistence_cls_name).
ENDIF.
CATCH cx_root.
zcx_abapgit_exception=>raise( |{ ms_item-obj_type } not supported| ).
ENDTRY.
ENDMETHOD.
METHOD get_data.
DATA: lv_object_key TYPE seu_objkey.
lv_object_key = ms_item-obj_name.
TRY.
mo_persistence->get(
EXPORTING
p_object_key = lv_object_key
p_version = 'A'
CHANGING
p_object_data = mo_appl_obj_data ).
CATCH cx_root.
zcx_abapgit_exception=>raise( |{ ms_item-obj_type } not supported| ).
ENDTRY.
mo_appl_obj_data->get_data(
IMPORTING
p_data = p_data ).
ENDMETHOD.
METHOD get_names.
IF mv_data_structure_name IS INITIAL.
mv_data_structure_name = get_data_structure_name( ).
ENDIF.
IF mv_appl_obj_cls_name IS INITIAL.
mv_appl_obj_cls_name = get_data_class_name( ).
ENDIF.
IF mv_persistence_cls_name IS INITIAL.
mv_persistence_cls_name = get_persistence_class_name( ).
ENDIF.
ENDMETHOD.
METHOD lock.
DATA: lv_objname TYPE trobj_name,
lv_object_key TYPE seu_objkey,
lv_objtype TYPE trobjtype.
lv_objname = ms_item-obj_name.
lv_object_key = ms_item-obj_name.
lv_objtype = ms_item-obj_type.
mo_persistence->lock(
EXPORTING
p_objname_tr = lv_objname
p_object_key = lv_object_key
p_objtype_tr = lv_objtype
EXCEPTIONS
foreign_lock = 1
error_occurred = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error occured while locking { ms_item-obj_type } | && lv_objname ).
ENDIF.
ENDMETHOD.
METHOD unlock.
DATA: lv_objname TYPE trobj_name,
lv_object_key TYPE seu_objkey,
lv_objtype TYPE trobjtype.
lv_objname = ms_item-obj_name.
lv_object_key = ms_item-obj_name.
lv_objtype = ms_item-obj_type.
mo_persistence->unlock( p_objname_tr = lv_objname
p_object_key = lv_object_key
p_objtype_tr = lv_objtype ).
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lr_data TYPE REF TO data.
FIELD-SYMBOLS: <lg_data> TYPE any,
<lg_header> TYPE any,
<lg_changed_by> TYPE any.
create_channel_objects( ).
TRY.
CREATE DATA lr_data TYPE (mv_data_structure_name).
ASSIGN lr_data->* TO <lg_data>.
CATCH cx_root.
zcx_abapgit_exception=>raise( |{ ms_item-obj_name } not supported| ).
ENDTRY.
get_data(
IMPORTING
p_data = <lg_data> ).
ASSIGN COMPONENT 'HEADER' OF STRUCTURE <lg_data> TO <lg_header>.
ASSERT sy-subrc = 0.
ASSIGN COMPONENT 'CHANGED_BY' OF STRUCTURE <lg_header> TO <lg_changed_by>.
ASSERT sy-subrc = 0.
IF <lg_changed_by> IS NOT INITIAL.
rv_user = <lg_changed_by>.
ELSE.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_object_key TYPE seu_objkey.
create_channel_objects( ).
lv_object_key = ms_item-obj_name.
TRY.
lock( ).
mo_persistence->delete( lv_object_key ).
unlock( ).
CATCH cx_swb_exception.
zcx_abapgit_exception=>raise( |Error occured while deleting { ms_item-obj_type }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lr_data TYPE REF TO data.
FIELD-SYMBOLS: <lg_data> TYPE any.
create_channel_objects( ).
TRY.
CREATE DATA lr_data TYPE (mv_data_structure_name).
ASSIGN lr_data->* TO <lg_data>.
CATCH cx_root.
zcx_abapgit_exception=>raise( |{ ms_item-obj_type } not supported| ).
ENDTRY.
io_xml->read(
EXPORTING
iv_name = ms_item-obj_type
CHANGING
cg_data = <lg_data> ).
IF zif_abapgit_object~exists( ) = abap_true.
zif_abapgit_object~delete( ).
ENDIF.
TRY.
lock( ).
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = ms_item-obj_name
object_class = ms_item-obj_type
mode = 'I'
global_lock = abap_true
devclass = iv_package
master_language = mv_language
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error occured while creating { ms_item-obj_type }| ).
ENDIF.
mo_appl_obj_data->set_data( <lg_data> ).
mo_persistence->save( mo_appl_obj_data ).
unlock( ).
CATCH cx_swb_exception.
zcx_abapgit_exception=>raise( |Error occured while creating { ms_item-obj_type }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_object_key TYPE seu_objkey.
create_channel_objects( ).
lv_object_key = ms_item-obj_name.
TRY.
mo_persistence->get( p_object_key = lv_object_key
p_version = 'A'
p_existence_check_only = abap_true ).
CATCH cx_swb_object_does_not_exist cx_swb_exception.
rv_bool = abap_false.
RETURN.
ENDTRY.
rv_bool = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lr_data TYPE REF TO data.
FIELD-SYMBOLS: <lg_data> TYPE any,
<lg_header> TYPE any,
<lg_field> TYPE any.
create_channel_objects( ).
TRY.
CREATE DATA lr_data TYPE (mv_data_structure_name).
ASSIGN lr_data->* TO <lg_data>.
CATCH cx_root.
zcx_abapgit_exception=>raise( |{ ms_item-obj_type } not supported| ).
ENDTRY.
get_data(
IMPORTING
p_data = <lg_data> ).
ASSIGN COMPONENT 'HEADER' OF STRUCTURE <lg_data> TO <lg_header>.
ASSERT sy-subrc = 0.
ASSIGN COMPONENT 'CHANGED_ON' OF STRUCTURE <lg_header> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CHANGED_BY' OF STRUCTURE <lg_header> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CHANGED_AT' OF STRUCTURE <lg_header> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CHANGED_CLNT' OF STRUCTURE <lg_header> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CREATED_ON' OF STRUCTURE <lg_header> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CREATED_BY' OF STRUCTURE <lg_header> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CREATED_AT' OF STRUCTURE <lg_header> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CREATED_CLNT' OF STRUCTURE <lg_header> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
io_xml->add( iv_name = ms_item-obj_type
ig_data = <lg_data> ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_objects_program IMPLEMENTATION.
METHOD is_text_locked.
DATA: lv_object TYPE eqegraarg.
lv_object = |*{ iv_program }|.
rv_is_text_locked = exists_a_lock_entry_for( iv_lock_object = 'EABAPTEXTE'
iv_argument = lv_object ).
ENDMETHOD.
METHOD is_cua_locked.
DATA: lv_object TYPE eqegraarg,
ls_cua TYPE zcl_abapgit_objects_program=>ty_cua.
lv_object = |CU{ iv_program }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_cua_locked = exists_a_lock_entry_for( iv_lock_object = 'ESCUAPAINT'
iv_argument = lv_object ).
ENDMETHOD.
METHOD is_any_dynpro_locked.
DATA: lt_dynpros TYPE zcl_abapgit_objects_program=>ty_dynpro_tt,
lv_object TYPE seqg3-garg.
FIELD-SYMBOLS: <ls_dynpro> TYPE zcl_abapgit_objects_program=>ty_dynpro.
lt_dynpros = serialize_dynpros( iv_program ).
LOOP AT lt_dynpros ASSIGNING <ls_dynpro>.
lv_object = |{ <ls_dynpro>-header-screen }{ <ls_dynpro>-header-program }|.
IF exists_a_lock_entry_for( iv_lock_object = 'ESCRP'
iv_argument = lv_object ) = abap_true.
rv_is_any_dynpro_locked = abap_true.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD condense_flow.
DATA: lv_spaces LIKE LINE OF et_spaces.
FIELD-SYMBOLS: <ls_flow> LIKE LINE OF ct_flow.
CLEAR et_spaces.
LOOP AT ct_flow ASSIGNING <ls_flow>.
lv_spaces = 0.
WHILE NOT <ls_flow>-line IS INITIAL AND <ls_flow>-line(1) = space.
lv_spaces = lv_spaces + 1.
<ls_flow>-line = <ls_flow>-line+1.
ENDWHILE.
APPEND lv_spaces TO et_spaces.
ENDLOOP.
ENDMETHOD.
METHOD uncondense_flow.
DATA: lv_spaces LIKE LINE OF it_spaces.
FIELD-SYMBOLS: <ls_flow> LIKE LINE OF it_flow,
<ls_output> LIKE LINE OF rt_flow.
LOOP AT it_flow ASSIGNING <ls_flow>.
APPEND INITIAL LINE TO rt_flow ASSIGNING <ls_output>.
<ls_output>-line = <ls_flow>-line.
READ TABLE it_spaces INDEX sy-tabix INTO lv_spaces.
IF sy-subrc = 0.
SHIFT <ls_output>-line RIGHT BY lv_spaces PLACES IN CHARACTER MODE.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD serialize_program.
DATA: ls_progdir TYPE ty_progdir,
lv_program_name TYPE programm,
lt_dynpros TYPE ty_dynpro_tt,
ls_cua TYPE ty_cua,
lt_source TYPE TABLE OF abaptxt255,
lt_tpool TYPE textpool_table,
ls_tpool LIKE LINE OF lt_tpool,
lo_xml TYPE REF TO zcl_abapgit_xml_output.
IF iv_program IS INITIAL.
lv_program_name = is_item-obj_name.
ELSE.
lv_program_name = iv_program.
ENDIF.
zcl_abapgit_language=>set_current_language( mv_language ).
CALL FUNCTION 'RPY_PROGRAM_READ'
EXPORTING
program_name = lv_program_name
with_lowercase = abap_true
TABLES
source_extended = lt_source
textelements = lt_tpool
EXCEPTIONS
cancelled = 1
not_found = 2
permission_error = 3
OTHERS = 4.
IF sy-subrc = 2.
zcl_abapgit_language=>restore_login_language( ).
RETURN.
ELSEIF sy-subrc <> 0.
zcl_abapgit_language=>restore_login_language( ).
zcx_abapgit_exception=>raise( 'Error reading program' ).
ENDIF.
zcl_abapgit_language=>restore_login_language( ).
ls_progdir = read_progdir( lv_program_name ).
IF io_xml IS BOUND.
lo_xml = io_xml.
ELSE.
CREATE OBJECT lo_xml.
ENDIF.
lo_xml->add( iv_name = 'PROGDIR'
ig_data = ls_progdir ).
IF ls_progdir-subc = '1' OR ls_progdir-subc = 'M'.
lt_dynpros = serialize_dynpros( lv_program_name ).
lo_xml->add( iv_name = 'DYNPROS'
ig_data = lt_dynpros ).
ls_cua = serialize_cua( lv_program_name ).
IF NOT ls_cua IS INITIAL.
lo_xml->add( iv_name = 'CUA'
ig_data = ls_cua ).
ENDIF.
ENDIF.
READ TABLE lt_tpool WITH KEY id = 'R' INTO ls_tpool.
IF sy-subrc = 0 AND ls_tpool-key = '' AND ls_tpool-length = 0.
DELETE lt_tpool INDEX sy-tabix.
ENDIF.
lo_xml->add( iv_name = 'TPOOL'
ig_data = add_tpool( lt_tpool ) ).
IF NOT io_xml IS BOUND.
io_files->add_xml( iv_extra = iv_extra
io_xml = lo_xml ).
ENDIF.
io_files->add_abap( iv_extra = iv_extra
it_abap = lt_source ).
ENDMETHOD.
METHOD deserialize_program.
DATA: lv_exists TYPE sap_bool,
lv_progname TYPE reposrc-progname,
ls_tpool LIKE LINE OF it_tpool,
lv_title TYPE rglif-title,
ls_progdir_new TYPE progdir.
FIELD-SYMBOLS: <lg_any> TYPE any.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = is_progdir-name
object_class = 'ABAP'
devclass = iv_package
master_language = mv_language
mode = 'INSERT'
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc = 1.
zcx_abapgit_exception=>raise( 'Cancelled' ).
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT' ).
ENDIF.
READ TABLE it_tpool INTO ls_tpool WITH KEY id = 'R'. "#EC CI_SUBRC
IF sy-subrc = 0.
ASSIGN ('(SAPLSIFP)TTAB') TO <lg_any>.
IF sy-subrc = 0.
CLEAR <lg_any>.
ENDIF.
lv_title = ls_tpool-entry.
ENDIF.
SELECT SINGLE progname FROM reposrc INTO lv_progname
WHERE progname = is_progdir-name
AND r3state = 'A'.
IF sy-subrc = 0.
lv_exists = abap_true.
ELSE.
lv_exists = abap_false.
ENDIF.
IF lv_exists = abap_true.
zcl_abapgit_language=>set_current_language( mv_language ).
CALL FUNCTION 'RPY_PROGRAM_UPDATE'
EXPORTING
program_name = is_progdir-name
title_string = lv_title
save_inactive = 'I'
TABLES
source_extended = it_source
EXCEPTIONS
cancelled = 1
permission_error = 2
not_found = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcl_abapgit_language=>restore_login_language( ).
IF sy-msgid = 'EU' AND sy-msgno = '510'.
zcx_abapgit_exception=>raise( 'User is currently editing program' ).
ELSE.
zcx_abapgit_exception=>raise( 'PROG, error updating' ).
ENDIF.
ENDIF.
zcl_abapgit_language=>restore_login_language( ).
ELSEIF strlen( is_progdir-name ) > 30.
" special treatment for extensions
" if the program name exceeds 30 characters it is not a usual
" ABAP program but might be some extension, which requires the internal
" addition EXTENSION TYPE, see
" http://help.sap.com/abapdocu_751/en/abapinsert_report_internal.htm#!ABAP_ADDITION_1@1@
" This e.g. occurs in case of transportable Code Inspector variants (ending with ===VC)
INSERT REPORT is_progdir-name
FROM it_source
STATE 'I'
EXTENSION TYPE is_progdir-name+30.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from INSERT REPORT .. EXTENSION TYPE' ).
ENDIF.
ELSE.
INSERT REPORT is_progdir-name
FROM it_source
STATE 'I'
PROGRAM TYPE is_progdir-subc.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from INSERT REPORT' ).
ENDIF.
ENDIF.
IF NOT it_tpool[] IS INITIAL.
INSERT TEXTPOOL is_progdir-name
FROM it_tpool
LANGUAGE mv_language
STATE 'I'.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from INSERT TEXTPOOL' ).
ENDIF.
ENDIF.
CALL FUNCTION 'READ_PROGDIR'
EXPORTING
i_progname = is_progdir-name
i_state = 'I'
IMPORTING
e_progdir = ls_progdir_new
EXCEPTIONS
not_exists = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'not found in PROGDIR' ).
ENDIF.
ls_progdir_new-ldbname = is_progdir-ldbname.
ls_progdir_new-dbna = is_progdir-dbna.
ls_progdir_new-dbapl = is_progdir-dbapl.
ls_progdir_new-rload = is_progdir-rload.
ls_progdir_new-fixpt = is_progdir-fixpt.
ls_progdir_new-varcl = is_progdir-varcl.
ls_progdir_new-appl = is_progdir-appl.
ls_progdir_new-rstat = is_progdir-rstat.
CALL FUNCTION 'UPDATE_PROGDIR'
EXPORTING
i_progdir = ls_progdir_new
i_progname = ls_progdir_new-name
i_state = ls_progdir_new-state
EXCEPTIONS
not_executed = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'PROG, error inserting' ).
ENDIF.
SELECT SINGLE * FROM progdir INTO ls_progdir_new
WHERE name = ls_progdir_new-name
AND state = ls_progdir_new-state.
IF sy-subrc = 0 AND is_progdir-varcl = space AND ls_progdir_new-varcl = abap_true.
UPDATE progdir SET varcl = is_progdir-varcl
WHERE name = ls_progdir_new-name
AND state = ls_progdir_new-state. "#EC CI_SUBRC
ENDIF.
zcl_abapgit_objects_activation=>add(
iv_type = 'REPS'
iv_name = is_progdir-name ).
ENDMETHOD.
METHOD read_progdir.
DATA: ls_sapdir TYPE progdir.
CALL FUNCTION 'READ_PROGDIR'
EXPORTING
i_progname = iv_program
i_state = 'A'
IMPORTING
e_progdir = ls_sapdir.
MOVE-CORRESPONDING ls_sapdir TO rs_progdir.
CLEAR: rs_progdir-edtx,
rs_progdir-cnam,
rs_progdir-cdat,
rs_progdir-unam,
rs_progdir-udat,
rs_progdir-levl,
rs_progdir-vern,
rs_progdir-rmand,
rs_progdir-sdate,
rs_progdir-stime,
rs_progdir-idate,
rs_progdir-itime.
ENDMETHOD.
METHOD serialize_cua.
CALL FUNCTION 'RS_CUA_INTERNAL_FETCH'
EXPORTING
program = iv_program_name
language = mv_language
state = 'A'
IMPORTING
adm = rs_cua-adm
TABLES
sta = rs_cua-sta
fun = rs_cua-fun
men = rs_cua-men
mtx = rs_cua-mtx
act = rs_cua-act
but = rs_cua-but
pfk = rs_cua-pfk
set = rs_cua-set
doc = rs_cua-doc
tit = rs_cua-tit
biv = rs_cua-biv
EXCEPTIONS
not_found = 1
unknown_version = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CUA_INTERNAL_FETCH' ).
ENDIF.
ENDMETHOD.
METHOD serialize_dynpros.
DATA: ls_header TYPE rpy_dyhead,
lt_containers TYPE dycatt_tab,
lt_fields_to_containers TYPE dyfatc_tab,
lt_flow_logic TYPE swydyflow,
lt_d020s TYPE TABLE OF d020s.
FIELD-SYMBOLS: <ls_d020s> LIKE LINE OF lt_d020s,
<lv_outputstyle> TYPE scrpostyle,
<ls_field> LIKE LINE OF lt_fields_to_containers,
<ls_dynpro> LIKE LINE OF rt_dynpro.
CALL FUNCTION 'RS_SCREEN_LIST'
EXPORTING
dynnr = ''
progname = iv_program_name
TABLES
dynpros = lt_d020s
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF sy-subrc = 2.
zcx_abapgit_exception=>raise( 'error from screen_list' ).
ENDIF.
LOOP AT lt_d020s ASSIGNING <ls_d020s>
WHERE type <> 'S' AND type <> 'W' AND type <> 'J'.
CALL FUNCTION 'RPY_DYNPRO_READ'
EXPORTING
progname = iv_program_name
dynnr = <ls_d020s>-dnum
IMPORTING
header = ls_header
TABLES
containers = lt_containers
fields_to_containers = lt_fields_to_containers
flow_logic = lt_flow_logic
EXCEPTIONS
cancelled = 1
not_found = 2
permission_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error while reading dynpro' ).
ENDIF.
LOOP AT lt_fields_to_containers ASSIGNING <ls_field>.
ASSIGN COMPONENT 'OUTPUTSTYLE' OF STRUCTURE <ls_field> TO <lv_outputstyle>.
IF sy-subrc = 0 AND <lv_outputstyle> = ' '.
CLEAR <lv_outputstyle>.
ENDIF.
ENDLOOP.
APPEND INITIAL LINE TO rt_dynpro ASSIGNING <ls_dynpro>.
<ls_dynpro>-header = ls_header.
<ls_dynpro>-containers = lt_containers.
<ls_dynpro>-fields = lt_fields_to_containers.
condense_flow( IMPORTING et_spaces = <ls_dynpro>-spaces
CHANGING ct_flow = lt_flow_logic ).
<ls_dynpro>-flow_logic = lt_flow_logic.
ENDLOOP.
ENDMETHOD.
METHOD deserialize_dynpros.
DATA: lv_name TYPE dwinactiv-obj_name,
ls_dynpro LIKE LINE OF it_dynpros.
LOOP AT it_dynpros INTO ls_dynpro.
ls_dynpro-flow_logic = uncondense_flow(
it_flow = ls_dynpro-flow_logic
it_spaces = ls_dynpro-spaces ).
CALL FUNCTION 'RPY_DYNPRO_INSERT'
EXPORTING
header = ls_dynpro-header
suppress_exist_checks = abap_true
TABLES
containers = ls_dynpro-containers
fields_to_containers = ls_dynpro-fields
flow_logic = ls_dynpro-flow_logic
EXCEPTIONS
cancelled = 1
already_exists = 2
program_not_exists = 3
not_executed = 4
missing_required_field = 5
illegal_field_value = 6
field_not_allowed = 7
not_generated = 8
illegal_field_position = 9
OTHERS = 10.
IF sy-subrc <> 2 AND sy-subrc <> 0.
zcx_abapgit_exception=>raise( |error from RPY_DYNPRO_INSERT: { sy-subrc }| ).
ENDIF.
CONCATENATE ls_dynpro-header-program ls_dynpro-header-screen
INTO lv_name RESPECTING BLANKS.
ASSERT NOT lv_name IS INITIAL.
zcl_abapgit_objects_activation=>add(
iv_type = 'DYNP'
iv_name = lv_name ).
ENDLOOP.
ENDMETHOD.
METHOD add_tpool.
FIELD-SYMBOLS: <ls_tpool_in> LIKE LINE OF it_tpool,
<ls_tpool_out> LIKE LINE OF rt_tpool.
LOOP AT it_tpool ASSIGNING <ls_tpool_in>.
APPEND INITIAL LINE TO rt_tpool ASSIGNING <ls_tpool_out>.
MOVE-CORRESPONDING <ls_tpool_in> TO <ls_tpool_out>.
IF <ls_tpool_out>-id = 'S'.
<ls_tpool_out>-split = <ls_tpool_out>-entry.
<ls_tpool_out>-entry = <ls_tpool_out>-entry+8.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD read_tpool.
FIELD-SYMBOLS: <ls_tpool_in> LIKE LINE OF it_tpool,
<ls_tpool_out> LIKE LINE OF rt_tpool.
LOOP AT it_tpool ASSIGNING <ls_tpool_in>.
APPEND INITIAL LINE TO rt_tpool ASSIGNING <ls_tpool_out>.
MOVE-CORRESPONDING <ls_tpool_in> TO <ls_tpool_out>.
IF <ls_tpool_out>-id = 'S'.
CONCATENATE <ls_tpool_in>-split <ls_tpool_in>-entry
INTO <ls_tpool_out>-entry
RESPECTING BLANKS.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD deserialize_textpool.
DATA lv_language TYPE langu.
DATA lv_state TYPE c.
DATA lv_delete TYPE abap_bool.
IF iv_language IS INITIAL.
lv_language = mv_language.
ELSE.
lv_language = iv_language.
ENDIF.
IF lv_language = mv_language.
lv_state = 'I'. "Textpool in master language needs to be activated
ELSE.
lv_state = 'A'. "Translations are always active
ENDIF.
IF it_tpool IS INITIAL.
IF iv_is_include = abap_false OR lv_state = 'A'.
DELETE TEXTPOOL iv_program "Remove initial description from textpool if
LANGUAGE iv_program "original program does not have a textpool
STATE lv_state.
lv_delete = abap_true.
ELSE.
INSERT TEXTPOOL iv_program "In case of includes: Deletion of textpool in
FROM it_tpool "master language cannot be activated because
LANGUAGE lv_language "this woul activate the deletion of the textpool
STATE lv_state. "of the mail program -> insert empty textpool
ENDIF.
ELSE.
IF lines( it_tpool ) = 1 AND lv_language = mv_language.
READ TABLE it_tpool WITH KEY id = 'R' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
RETURN. "No action because description in master language is already there
ENDIF.
ENDIF.
INSERT TEXTPOOL iv_program
FROM it_tpool
LANGUAGE lv_language
STATE lv_state.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from INSERT TEXTPOOL' ).
ENDIF.
ENDIF.
IF lv_state = 'I'. "Textpool in master language needs to be activated
zcl_abapgit_objects_activation=>add(
iv_type = 'REPT'
iv_name = iv_program
iv_delete = lv_delete ).
ENDIF.
ENDMETHOD.
METHOD deserialize_cua.
DATA: ls_tr_key TYPE trkey,
ls_adm TYPE rsmpe_adm.
IF lines( is_cua-sta ) = 0
AND lines( is_cua-fun ) = 0
AND lines( is_cua-men ) = 0
AND lines( is_cua-mtx ) = 0
AND lines( is_cua-act ) = 0
AND lines( is_cua-but ) = 0
AND lines( is_cua-pfk ) = 0
AND lines( is_cua-set ) = 0
AND lines( is_cua-doc ) = 0
AND lines( is_cua-tit ) = 0
AND lines( is_cua-biv ) = 0.
RETURN.
ENDIF.
SELECT SINGLE devclass INTO ls_tr_key-devclass
FROM tadir
WHERE pgmid = 'R3TR'
AND object = ms_item-obj_type
AND obj_name = ms_item-obj_name. "#EC CI_GENBUFF
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'not found in tadir' ).
ENDIF.
ls_tr_key-obj_type = ms_item-obj_type.
ls_tr_key-obj_name = ms_item-obj_name.
ls_tr_key-sub_type = 'CUAD'.
ls_tr_key-sub_name = iv_program_name.
ls_adm = is_cua-adm.
auto_correct_cua_adm( EXPORTING is_cua = is_cua CHANGING cs_adm = ls_adm ).
sy-tcode = 'SE41' ##write_ok. " evil hack, workaround to handle fixes in note 2159455
CALL FUNCTION 'RS_CUA_INTERNAL_WRITE'
EXPORTING
program = iv_program_name
language = mv_language
tr_key = ls_tr_key
adm = ls_adm
state = 'I'
TABLES
sta = is_cua-sta
fun = is_cua-fun
men = is_cua-men
mtx = is_cua-mtx
act = is_cua-act
but = is_cua-but
pfk = is_cua-pfk
set = is_cua-set
doc = is_cua-doc
tit = is_cua-tit
biv = is_cua-biv
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CUA_INTERNAL_WRITE' ).
ENDIF.
zcl_abapgit_objects_activation=>add(
iv_type = 'CUAD'
iv_name = iv_program_name ).
ENDMETHOD.
METHOD check_prog_changed_since.
DATA: lv_date TYPE dats,
lv_time TYPE tims,
lt_screens TYPE STANDARD TABLE OF d020s,
lt_eudb TYPE STANDARD TABLE OF eudb.
FIELD-SYMBOLS: <ls_screen> LIKE LINE OF lt_screens,
<ls_eudb> LIKE LINE OF lt_eudb.
SELECT SINGLE udat utime FROM reposrc " Program
INTO (lv_date, lv_time)
WHERE progname = iv_program
AND r3state = 'A'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
SELECT SINGLE udat utime FROM repotext " Program text pool
INTO (lv_date, lv_time)
WHERE progname = iv_program
AND r3state = 'A'.
IF sy-subrc = 0. " Text not found ? Assuming no changes, see #404
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
ENDIF.
IF iv_skip_gui = abap_true.
RETURN.
ENDIF.
SELECT dgen tgen FROM d020s " Screens
INTO CORRESPONDING FIELDS OF TABLE lt_screens
WHERE prog = iv_program
ORDER BY PRIMARY KEY ##TOO_MANY_ITAB_FIELDS. "#EC CI_SUBRC
LOOP AT lt_screens ASSIGNING <ls_screen>.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = <ls_screen>-dgen
iv_time = <ls_screen>-tgen ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
ENDLOOP.
SELECT vdatum vzeit FROM eudb " GUI
INTO CORRESPONDING FIELDS OF TABLE lt_eudb
WHERE relid = 'CU'
AND name = iv_program
AND srtf2 = 0
ORDER BY PRIMARY KEY ##TOO_MANY_ITAB_FIELDS. "#EC CI_SUBRC
LOOP AT lt_eudb ASSIGNING <ls_eudb>.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = <ls_eudb>-vdatum
iv_time = <ls_eudb>-vzeit ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD auto_correct_cua_adm.
" issue #1807 automatic correction of CUA interfaces saved incorrectly in the past (ADM was not saved in the XML)
FIELD-SYMBOLS:
<ls_pfk> TYPE rsmpe_pfk,
<ls_act> TYPE rsmpe_act,
<ls_men> TYPE rsmpe_men.
IF cs_adm IS NOT INITIAL.
RETURN.
ENDIF.
LOOP AT is_cua-act ASSIGNING <ls_act>.
IF <ls_act>-code+6(14) IS INITIAL AND <ls_act>-code(6) CO '0123456789'.
cs_adm-actcode = <ls_act>-code.
ENDIF.
ENDLOOP.
LOOP AT is_cua-men ASSIGNING <ls_men>.
IF <ls_men>-code+6(14) IS INITIAL AND <ls_men>-code(6) CO '0123456789'.
cs_adm-mencode = <ls_men>-code.
ENDIF.
ENDLOOP.
LOOP AT is_cua-pfk ASSIGNING <ls_pfk>.
IF <ls_pfk>-code+6(14) IS INITIAL AND <ls_pfk>-code(6) CO '0123456789'.
cs_adm-pfkcode = <ls_pfk>-code.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECTS_GENERIC IMPLEMENTATION.
METHOD after_import.
DATA: lt_cts_object_entry TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY,
ls_cts_object_entry LIKE LINE OF lt_cts_object_entry,
lt_cts_key TYPE STANDARD TABLE OF e071k WITH DEFAULT KEY.
FIELD-SYMBOLS <ls_object_method> LIKE LINE OF mt_object_method.
ls_cts_object_entry-pgmid = rs_c_pgmid_r3tr.
ls_cts_object_entry-object = ms_item-obj_type.
ls_cts_object_entry-obj_name = ms_item-obj_name.
INSERT ls_cts_object_entry INTO TABLE lt_cts_object_entry.
READ TABLE mt_object_method ASSIGNING <ls_object_method>
WITH KEY
objectname = ms_item-obj_type
objecttype = 'L'
method = 'AFTER_IMP'.
IF sy-subrc = 0.
CALL FUNCTION <ls_object_method>-methodname
EXPORTING
iv_tarclient = sy-mandt
iv_is_upgrade = abap_false
TABLES
tt_e071 = lt_cts_object_entry
tt_e071k = lt_cts_key.
ENDIF.
ENDMETHOD.
METHOD before_export.
DATA: lt_cts_object_entry TYPE STANDARD TABLE OF e071 WITH DEFAULT KEY,
ls_cts_object_entry LIKE LINE OF lt_cts_object_entry,
lt_cts_key TYPE STANDARD TABLE OF e071k WITH DEFAULT KEY,
lv_client TYPE trclient.
FIELD-SYMBOLS <ls_object_method> LIKE LINE OF mt_object_method.
READ TABLE mt_object_method ASSIGNING <ls_object_method>
WITH KEY
objectname = ms_item-obj_type
objecttype = 'L'
method = 'BEFORE_EXP' ##no_text.
IF sy-subrc = 0.
lv_client = sy-mandt.
ls_cts_object_entry-pgmid = rs_c_pgmid_r3tr.
ls_cts_object_entry-object = ms_item-obj_type.
ls_cts_object_entry-obj_name = ms_item-obj_name.
INSERT ls_cts_object_entry INTO TABLE lt_cts_object_entry.
CALL FUNCTION <ls_object_method>-methodname
EXPORTING
iv_client = lv_client
TABLES
tt_e071 = lt_cts_object_entry
tt_e071k = lt_cts_key.
ENDIF.
ENDMETHOD.
METHOD constructor.
CONSTANTS lc_logical_transport_object TYPE c LENGTH 1 VALUE 'L'.
SELECT SINGLE * FROM objh INTO ms_object_header
WHERE objectname = is_item-obj_type
AND objecttype = lc_logical_transport_object.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Not found in OBJH, or not supported' ).
ENDIF.
SELECT * FROM objsl INTO CORRESPONDING FIELDS OF TABLE mt_object_table
WHERE objectname = is_item-obj_type
AND objecttype = lc_logical_transport_object
AND tobject = 'TABU'.
IF mt_object_table IS INITIAL.
zcx_abapgit_exception=>raise( |Obviously corrupted object-type {
is_item-obj_type }: No tables defined| ).
ENDIF.
SELECT * FROM objm INTO TABLE mt_object_method
WHERE objectname = is_item-obj_type
AND objecttype = lc_logical_transport_object.
ms_item = is_item.
ENDMETHOD.
METHOD corr_insert.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = ms_item-obj_name
object_class = ms_item-obj_type
mode = 'I'
global_lock = abap_true
devclass = iv_package
master_language = sy-langu
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT, CMPT' ).
ENDIF.
ENDMETHOD.
METHOD delete.
DATA: lv_where TYPE string,
lv_primary TYPE objsl-tobj_name.
FIELD-SYMBOLS <ls_table> LIKE LINE OF mt_object_table.
lv_primary = get_primary_table( ).
LOOP AT mt_object_table ASSIGNING <ls_table>.
lv_where = get_where_clause( <ls_table>-tobj_name ).
ASSERT NOT lv_where IS INITIAL.
DELETE FROM (<ls_table>-tobj_name) WHERE (lv_where).
IF <ls_table>-tobj_name = lv_primary.
ASSERT sy-dbcnt <= 1. "Just to be on the very safe side
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD deserialize.
validate( io_xml ).
delete( ).
deserialize_data( io_xml ).
after_import( ).
corr_insert( iv_package ).
ENDMETHOD.
METHOD deserialize_data.
DATA: lr_ref TYPE REF TO data.
FIELD-SYMBOLS: <lt_data> TYPE STANDARD TABLE,
<ls_table> LIKE LINE OF mt_object_table.
LOOP AT mt_object_table ASSIGNING <ls_table>.
CREATE DATA lr_ref TYPE STANDARD TABLE OF (<ls_table>-tobj_name).
ASSIGN lr_ref->* TO <lt_data>.
io_xml->read(
EXPORTING
iv_name = <ls_table>-tobj_name
CHANGING
cg_data = <lt_data> ).
INSERT (<ls_table>-tobj_name) FROM TABLE <lt_data>.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error inserting data, {
<ls_table>-tobj_name }| ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD distribute_name_to_components.
DATA: lt_key_component_uncovered LIKE it_key_component,
ls_key_component_uncovered LIKE LINE OF lt_key_component_uncovered,
ls_objkey_sub LIKE cs_objkey,
lv_objkey_sub_pos TYPE i,
lv_remaining_length TYPE i,
lv_count_components_covered LIKE ls_objkey_sub-num.
DATA lv_len LIKE ls_key_component_uncovered-leng.
lt_key_component_uncovered = it_key_component.
ls_objkey_sub-num = cs_objkey-num.
lv_objkey_sub_pos = 0.
lv_count_components_covered = ls_objkey_sub-num - 1.
DO lv_count_components_covered TIMES.
DELETE lt_key_component_uncovered INDEX 1.
ENDDO.
LOOP AT lt_key_component_uncovered INTO ls_key_component_uncovered.
CLEAR ls_objkey_sub-value.
TRY.
lv_remaining_length = strlen( |{ substring( val = cs_objkey-value off = lv_objkey_sub_pos ) }| ).
CATCH cx_sy_range_out_of_bounds.
lv_remaining_length = 0.
RETURN. ">>>>>>>>>>>>>>>>>>>>>>>>>>>
ENDTRY.
IF ls_key_component_uncovered-leng <= lv_remaining_length.
lv_len = ls_key_component_uncovered-leng.
ELSE.
lv_len = lv_remaining_length.
ENDIF.
ls_objkey_sub-value = |{ substring( val = cs_objkey-value off = lv_objkey_sub_pos len = lv_len ) }|.
ls_objkey_sub-num = cv_non_value_pos.
INSERT ls_objkey_sub INTO TABLE ct_objkey.
lv_objkey_sub_pos = lv_objkey_sub_pos + ls_key_component_uncovered-leng.
cv_non_value_pos = cv_non_value_pos + 1.
CLEAR ls_objkey_sub.
IF lv_objkey_sub_pos = strlen( cs_objkey-value ).
cs_objkey-num = cv_non_value_pos.
EXIT. "end splitting - all characters captured
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD exists.
DATA: lv_where_clause TYPE string,
lv_primary TYPE objsl-tobj_name,
lr_table_line TYPE REF TO data.
FIELD-SYMBOLS: <lg_table_line> TYPE any.
lv_primary = get_primary_table( ).
lv_where_clause = get_where_clause( lv_primary ).
CREATE DATA lr_table_line TYPE (lv_primary).
ASSIGN lr_table_line->* TO <lg_table_line>.
SELECT SINGLE * FROM (lv_primary) INTO <lg_table_line> WHERE (lv_where_clause).
rv_bool = boolc( sy-dbcnt > 0 ).
ENDMETHOD.
METHOD get_key_fields.
DATA: lv_table TYPE ddobjname.
lv_table = iv_table.
CALL FUNCTION 'DDIF_NAMETAB_GET'
EXPORTING
tabname = lv_table
TABLES
dfies_tab = rt_keys
EXCEPTIONS
not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
DELETE rt_keys WHERE keyflag = abap_false.
ENDMETHOD.
METHOD get_primary_table.
DATA: ls_object_table LIKE LINE OF mt_object_table.
READ TABLE mt_object_table INTO ls_object_table WITH KEY prim_table = abap_true.
IF sy-subrc <> 0.
READ TABLE mt_object_table INTO ls_object_table WITH KEY tobjkey = '/&'. "#EC CI_SUBRC
ENDIF.
IF ls_object_table IS INITIAL.
zcx_abapgit_exception=>raise( |Object { ms_item-obj_type } has got no defined primary table| ).
ENDIF.
rv_table = ls_object_table-tobj_name.
ENDMETHOD.
METHOD get_where_clause.
DATA: lv_objkey_pos TYPE i,
lv_next_objkey_pos TYPE i,
lv_value_pos TYPE i,
lv_objkey_length TYPE i,
lt_objkey TYPE ty_t_objkey,
ls_objkey LIKE LINE OF lt_objkey,
lv_non_value_pos TYPE numc3,
lt_key_fields TYPE ddfields.
DATA: lv_is_asterix TYPE abap_bool,
lv_where_statement TYPE string,
lv_key_pos TYPE i,
lv_value128 TYPE string.
FIELD-SYMBOLS <ls_object_table> LIKE LINE OF mt_object_table.
FIELD-SYMBOLS <ls_table_field> LIKE LINE OF lt_key_fields.
READ TABLE mt_object_table ASSIGNING <ls_object_table> WITH KEY tobj_name = iv_tobj_name.
ASSERT sy-subrc = 0.
lt_key_fields = get_key_fields( iv_tobj_name ).
CLEAR lt_objkey.
CLEAR ls_objkey.
lv_objkey_pos = 0.
lv_non_value_pos = 1.
lv_value_pos = 0.
lv_objkey_length = strlen( <ls_object_table>-tobjkey ).
WHILE lv_objkey_pos <= lv_objkey_length.
ls_objkey-num = lv_non_value_pos.
IF <ls_object_table>-tobjkey+lv_objkey_pos(1) = '/'.
IF NOT ls_objkey-value IS INITIAL.
split_value_to_keys(
EXPORTING
it_key_component = lt_key_fields
CHANGING
ct_objkey = lt_objkey
cs_objkey = ls_objkey
cv_non_value_pos = lv_non_value_pos ).
ENDIF.
lv_next_objkey_pos = lv_objkey_pos + 1.
IF <ls_object_table>-tobjkey+lv_next_objkey_pos(1) = '*'.
ls_objkey-value = '*'.
INSERT ls_objkey INTO TABLE lt_objkey.
CLEAR ls_objkey.
lv_non_value_pos = lv_non_value_pos + 1.
lv_objkey_pos = lv_objkey_pos + 1.
ELSEIF <ls_object_table>-tobjkey+lv_next_objkey_pos(1) = '&'.
"TODO
ls_objkey-value = ms_item-obj_name.
distribute_name_to_components(
EXPORTING
it_key_component = lt_key_fields
CHANGING
ct_objkey = lt_objkey
cs_objkey = ls_objkey
cv_non_value_pos = lv_non_value_pos ).
CLEAR ls_objkey.
lv_objkey_pos = lv_objkey_pos + 1.
ELSEIF <ls_object_table>-tobjkey+lv_next_objkey_pos(1) = 'L'.
ls_objkey-value = sy-langu.
INSERT ls_objkey INTO TABLE lt_objkey.
CLEAR ls_objkey.
lv_non_value_pos = lv_non_value_pos + 1.
lv_objkey_pos = lv_objkey_pos + 1.
ELSEIF <ls_object_table>-tobjkey+lv_next_objkey_pos(1) = 'C'.
ls_objkey-value = sy-mandt.
INSERT ls_objkey INTO TABLE lt_objkey.
CLEAR ls_objkey.
lv_non_value_pos = lv_non_value_pos + 1.
lv_objkey_pos = lv_objkey_pos + 1.
ENDIF.
lv_value_pos = 0.
ELSE.
ls_objkey-value+lv_value_pos(1) = <ls_object_table>-tobjkey+lv_objkey_pos(1).
lv_value_pos = lv_value_pos + 1.
ENDIF.
lv_objkey_pos = lv_objkey_pos + 1.
ENDWHILE.
IF NOT ls_objkey-value IS INITIAL.
split_value_to_keys(
EXPORTING
it_key_component = lt_key_fields
CHANGING
ct_objkey = lt_objkey
cs_objkey = ls_objkey
cv_non_value_pos = lv_non_value_pos ).
ENDIF.
lv_is_asterix = abap_false.
lv_key_pos = 1.
LOOP AT lt_key_fields ASSIGNING <ls_table_field>.
READ TABLE lt_objkey INTO ls_objkey
WITH TABLE KEY num = lv_key_pos.
IF sy-subrc <> 0 OR <ls_table_field>-fieldname = 'LANGU'.
CLEAR ls_objkey.
lv_key_pos = lv_key_pos + 1.
CONTINUE.
ENDIF.
IF ls_objkey-value = '*'.
lv_is_asterix = rs_c_true.
ENDIF.
IF lv_is_asterix = rs_c_true.
CONTINUE.
ENDIF.
IF NOT lv_where_statement IS INITIAL.
CONCATENATE lv_where_statement 'AND' INTO lv_where_statement
SEPARATED BY space.
ENDIF.
lv_value128 = cl_abap_dyn_prg=>quote( ls_objkey-value ).
CONCATENATE lv_where_statement <ls_table_field>-fieldname '='
lv_value128 INTO lv_where_statement SEPARATED BY space.
lv_key_pos = lv_key_pos + 1.
ENDLOOP.
rv_where = condense( lv_where_statement ).
ENDMETHOD.
METHOD serialize.
before_export( ).
serialize_data( io_xml ).
ENDMETHOD.
METHOD serialize_data.
DATA: lr_ref TYPE REF TO data,
lv_where TYPE string.
FIELD-SYMBOLS: <lt_data> TYPE STANDARD TABLE,
<ls_object_table> LIKE LINE OF mt_object_table.
LOOP AT mt_object_table ASSIGNING <ls_object_table>.
CREATE DATA lr_ref TYPE STANDARD TABLE OF (<ls_object_table>-tobj_name).
ASSIGN lr_ref->* TO <lt_data>.
lv_where = get_where_clause( <ls_object_table>-tobj_name ).
SELECT * FROM (<ls_object_table>-tobj_name)
INTO TABLE <lt_data>
WHERE (lv_where).
io_xml->add(
iv_name = <ls_object_table>-tobj_name
ig_data = <lt_data> ).
ENDLOOP.
ENDMETHOD.
METHOD split_value_to_keys.
DATA: lt_key_component_uncovered LIKE it_key_component,
ls_dummy LIKE LINE OF ct_objkey,
ls_key_component_uncovered LIKE LINE OF lt_key_component_uncovered,
ls_objkey_sub LIKE cs_objkey,
lv_objkey_sub_pos TYPE i.
lt_key_component_uncovered = it_key_component.
LOOP AT ct_objkey INTO ls_dummy.
DELETE lt_key_component_uncovered INDEX 1.
ENDLOOP.
ls_objkey_sub-num = cs_objkey-num.
lv_objkey_sub_pos = 0.
LOOP AT lt_key_component_uncovered INTO ls_key_component_uncovered.
CLEAR ls_objkey_sub-value.
ls_objkey_sub-value = cs_objkey-value+lv_objkey_sub_pos(ls_key_component_uncovered-leng).
ls_objkey_sub-num = cv_non_value_pos.
INSERT ls_objkey_sub INTO TABLE ct_objkey.
lv_objkey_sub_pos = lv_objkey_sub_pos + ls_key_component_uncovered-leng.
cv_non_value_pos = cv_non_value_pos + 1.
CLEAR ls_objkey_sub.
IF lv_objkey_sub_pos = strlen( cs_objkey-value ).
cs_objkey-num = cv_non_value_pos.
EXIT. "end splitting - all characters captured
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD validate.
DATA: lv_where TYPE string,
lv_primary TYPE objsl-tobj_name,
lr_ref TYPE REF TO data.
FIELD-SYMBOLS: <lt_data> TYPE STANDARD TABLE.
lv_primary = get_primary_table( ).
CREATE DATA lr_ref TYPE STANDARD TABLE OF (lv_primary).
ASSIGN lr_ref->* TO <lt_data>.
io_xml->read(
EXPORTING
iv_name = lv_primary
CHANGING
cg_data = <lt_data> ).
IF lines( <lt_data> ) = 0.
zcx_abapgit_exception=>raise( |Primary table { lv_primary
} not found in imported container | ).
ELSEIF lines( <lt_data> ) <> 1.
zcx_abapgit_exception=>raise( |Primary table { lv_primary
} contains more than one instance! | ).
ENDIF.
lv_where = get_where_clause( lv_primary ).
SELECT COUNT(*) FROM (lv_primary) WHERE (lv_where).
IF sy-dbcnt > 1.
zcx_abapgit_exception=>raise( |More than one instance exists locally in primary table {
lv_primary }| ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECTS_FILES IMPLEMENTATION.
METHOD add.
APPEND is_file TO mt_files.
ENDMETHOD.
METHOD add_abap.
DATA: lv_source TYPE string,
ls_file TYPE zif_abapgit_definitions=>ty_file.
CONCATENATE LINES OF it_abap INTO lv_source SEPARATED BY zif_abapgit_definitions=>c_newline.
lv_source = lv_source && zif_abapgit_definitions=>c_newline.
ls_file-path = '/'.
ls_file-filename = filename( iv_extra = iv_extra
iv_ext = 'abap' ). "#EC NOTEXT
ls_file-data = zcl_abapgit_convert=>string_to_xstring_utf8( lv_source ).
APPEND ls_file TO mt_files.
ENDMETHOD.
METHOD add_raw.
DATA: ls_file TYPE zif_abapgit_definitions=>ty_file.
ls_file-path = '/'.
ls_file-data = iv_data.
ls_file-filename = filename( iv_extra = iv_extra
iv_ext = iv_ext ).
APPEND ls_file TO mt_files.
ENDMETHOD.
METHOD add_string.
DATA: ls_file TYPE zif_abapgit_definitions=>ty_file.
ls_file-path = '/'.
ls_file-filename = filename( iv_extra = iv_extra
iv_ext = iv_ext ). "#EC NOTEXT
ls_file-data = zcl_abapgit_convert=>string_to_xstring_utf8( iv_string ).
APPEND ls_file TO mt_files.
ENDMETHOD.
METHOD add_xml.
DATA: lv_xml TYPE string,
ls_file TYPE zif_abapgit_definitions=>ty_file.
lv_xml = io_xml->render( iv_normalize = iv_normalize
is_metadata = is_metadata ).
ls_file-path = '/'.
ls_file-filename = filename( iv_extra = iv_extra
iv_ext = 'xml' ). "#EC NOTEXT
REPLACE FIRST OCCURRENCE
OF REGEX '<\?xml version="1\.0" encoding="[\w-]+"\?>'
IN lv_xml
WITH '<?xml version="1.0" encoding="utf-8"?>'.
ASSERT sy-subrc = 0.
ls_file-data = zcl_abapgit_convert=>string_to_xstring_utf8( lv_xml ).
APPEND ls_file TO mt_files.
ENDMETHOD.
METHOD add_xml_from_plugin.
DATA lo_xml TYPE REF TO zcl_abapgit_xml_output.
lo_xml ?= io_xml.
me->add_xml(
iv_extra = iv_extra
io_xml = lo_xml
iv_normalize = iv_normalize ).
ENDMETHOD.
METHOD constructor.
ms_item = is_item.
mv_path = iv_path.
ENDMETHOD.
METHOD filename.
DATA: lv_obj_name TYPE string.
lv_obj_name = ms_item-obj_name.
IF ms_item-obj_type = 'DEVC'.
" Packages have a fixed filename so that the repository can be installed to a different
" package(-hierarchy) on the client and not show up as a different package in the repo.
lv_obj_name = 'package'.
ENDIF.
IF iv_extra IS INITIAL.
CONCATENATE lv_obj_name '.' ms_item-obj_type '.' iv_ext
INTO rv_filename. "#EC NOTEXT
ELSE.
CONCATENATE lv_obj_name '.' ms_item-obj_type '.' iv_extra '.' iv_ext
INTO rv_filename. "#EC NOTEXT
ENDIF.
REPLACE ALL OCCURRENCES OF '/' IN rv_filename WITH '#'.
TRANSLATE rv_filename TO LOWER CASE.
ENDMETHOD.
METHOD get_accessed_files.
rt_files = mt_accessed_files.
ENDMETHOD.
METHOD get_files.
rt_files = mt_files.
ENDMETHOD.
METHOD read_abap.
DATA: lv_filename TYPE string,
lv_data TYPE xstring,
lv_abap TYPE string.
lv_filename = filename( iv_extra = iv_extra
iv_ext = 'abap' ). "#EC NOTEXT
read_file( EXPORTING iv_filename = lv_filename
iv_error = iv_error
IMPORTING ev_data = lv_data ).
IF lv_data IS INITIAL. " Post-handling of iv_error = false
RETURN.
ENDIF.
lv_abap = zcl_abapgit_convert=>xstring_to_string_utf8( lv_data ).
SPLIT lv_abap AT zif_abapgit_definitions=>c_newline INTO TABLE rt_abap.
ENDMETHOD.
METHOD read_file.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF mt_files,
<ls_accessed> LIKE LINE OF mt_accessed_files.
CLEAR ev_data.
IF mv_path IS NOT INITIAL.
READ TABLE mt_files ASSIGNING <ls_file> WITH KEY path = mv_path
filename = iv_filename.
ELSE.
READ TABLE mt_files ASSIGNING <ls_file> WITH KEY filename = iv_filename.
ENDIF.
IF sy-subrc <> 0.
IF iv_error = abap_true.
zcx_abapgit_exception=>raise( |File not found: { iv_filename }| ).
ELSE.
RETURN.
ENDIF.
ENDIF.
" Update access table
READ TABLE mt_accessed_files TRANSPORTING NO FIELDS
WITH KEY path = <ls_file>-path filename = <ls_file>-filename.
IF sy-subrc > 0. " Not found ? -> Add
APPEND INITIAL LINE TO mt_accessed_files ASSIGNING <ls_accessed>.
MOVE-CORRESPONDING <ls_file> TO <ls_accessed>.
ENDIF.
ev_data = <ls_file>-data.
ENDMETHOD.
METHOD read_raw.
DATA: lv_filename TYPE string.
lv_filename = filename( iv_extra = iv_extra
iv_ext = iv_ext ).
read_file( EXPORTING iv_filename = lv_filename
IMPORTING ev_data = rv_data ).
ENDMETHOD.
METHOD read_string.
DATA: lv_filename TYPE string,
lv_data TYPE xstring.
lv_filename = filename( iv_extra = iv_extra
iv_ext = iv_ext ). "#EC NOTEXT
read_file( EXPORTING iv_filename = lv_filename
IMPORTING ev_data = lv_data ).
rv_string = zcl_abapgit_convert=>xstring_to_string_utf8( lv_data ).
ENDMETHOD.
METHOD read_xml.
DATA: lv_filename TYPE string,
lv_data TYPE xstring,
lv_xml TYPE string.
lv_filename = filename( iv_extra = iv_extra
iv_ext = 'xml' ). "#EC NOTEXT
read_file( EXPORTING iv_filename = lv_filename
IMPORTING ev_data = lv_data ).
lv_xml = zcl_abapgit_convert=>xstring_to_string_utf8( lv_data ).
CREATE OBJECT ro_xml
EXPORTING
iv_xml = lv_xml.
ENDMETHOD.
METHOD set_files.
mt_files = it_files.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECTS_ACTIVATION IMPLEMENTATION.
METHOD activate.
IF use_new_activation_logic( ) = abap_true.
activate_new( iv_ddic ).
ELSE.
activate_old( iv_ddic ).
ENDIF.
update_where_used( ).
ENDMETHOD.
METHOD activate_ddic.
DATA: lt_gentab TYPE STANDARD TABLE OF dcgentb,
ls_gentab LIKE LINE OF lt_gentab,
lv_rc TYPE sy-subrc,
lt_deltab TYPE STANDARD TABLE OF dcdeltb,
lt_action_tab TYPE STANDARD TABLE OF dctablres,
lv_logname TYPE ddmass-logname,
lv_errmsg(255) TYPE c.
FIELD-SYMBOLS: <ls_object> LIKE LINE OF gt_objects.
LOOP AT gt_objects ASSIGNING <ls_object>.
ls_gentab-name = <ls_object>-obj_name.
ls_gentab-type = <ls_object>-object.
INSERT ls_gentab INTO TABLE lt_gentab.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = <ls_object>-obj_name
object_class = <ls_object>-object
global_lock = abap_true
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc <> 0.
CONCATENATE 'error from RS_CORR_INSERT for' <ls_object>-object <ls_object>-obj_name
INTO lv_errmsg SEPARATED BY space.
zcx_abapgit_exception=>raise( lv_errmsg ).
ENDIF.
ENDLOOP.
IF lt_gentab IS NOT INITIAL.
lv_logname = |ABAPGIT_{ sy-datum }_{ sy-uzeit }|.
CALL FUNCTION 'DD_MASS_ACT_C3'
EXPORTING
ddmode = 'C'
medium = 'T'
device = 'T'
logname = lv_logname
write_log = abap_true
log_head_tail = abap_true
t_on = space
prid = 1
IMPORTING
act_rc = lv_rc
TABLES
gentab = lt_gentab
deltab = lt_deltab
cnvtab = lt_action_tab
EXCEPTIONS
access_failure = 1
no_objects = 2
locked = 3
internal_error = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DD_MASS_ACT_C3' ).
ENDIF.
IF lv_rc > 0.
show_activation_errors( lv_logname ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD activate_new.
DATA: lo_progress TYPE REF TO zcl_abapgit_progress.
IF gt_objects IS INITIAL.
RETURN.
ENDIF.
CREATE OBJECT lo_progress
EXPORTING
iv_total = 100.
IF iv_ddic = abap_true.
lo_progress->show( iv_current = 98
iv_text = 'Activating DDIC' ).
activate_ddic( ).
ELSE.
lo_progress->show( iv_current = 98
iv_text = 'Activating non DDIC' ).
activate_old( ).
ENDIF.
ENDMETHOD.
METHOD activate_old.
DATA: lv_popup TYPE abap_bool.
IF gt_objects IS NOT INITIAL.
CALL FUNCTION 'GUI_IS_AVAILABLE'
IMPORTING
return = lv_popup.
CALL FUNCTION 'RS_WORKING_OBJECTS_ACTIVATE'
EXPORTING
activate_ddic_objects = iv_ddic
with_popup = lv_popup
TABLES
objects = gt_objects
EXCEPTIONS
excecution_error = 1
cancelled = 2
insert_into_corr_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_WORKING_OBJECTS_ACTIVATE' ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD add.
DATA: lt_objects TYPE dwinactiv_tab,
lv_obj_name TYPE dwinactiv-obj_name.
FIELD-SYMBOLS: <ls_object> LIKE LINE OF lt_objects.
lv_obj_name = iv_name.
CASE iv_type.
WHEN 'CLAS'.
APPEND iv_name TO gt_classes.
WHEN 'WDYN'.
CALL FUNCTION 'RS_INACTIVE_OBJECTS_IN_OBJECT'
EXPORTING
obj_name = lv_obj_name
object = iv_type
TABLES
inactive_objects = lt_objects
EXCEPTIONS
object_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RS_INACTIVE_OBJECTS_IN_OBJECT' ).
ENDIF.
LOOP AT lt_objects ASSIGNING <ls_object>.
<ls_object>-delet_flag = iv_delete.
ENDLOOP.
APPEND LINES OF lt_objects TO gt_objects.
WHEN OTHERS.
APPEND INITIAL LINE TO gt_objects ASSIGNING <ls_object>.
<ls_object>-object = iv_type.
<ls_object>-obj_name = lv_obj_name.
<ls_object>-delet_flag = iv_delete.
ENDCASE.
ENDMETHOD.
METHOD add_item.
add( iv_type = is_item-obj_type
iv_name = is_item-obj_name ).
ENDMETHOD.
METHOD clear.
CLEAR gt_objects.
CLEAR gt_classes.
ENDMETHOD.
METHOD fix_class_methods.
DATA: lt_methods TYPE seop_methods_w_include,
lv_class TYPE seoclsname.
FIELD-SYMBOLS: <ls_method> LIKE LINE OF lt_methods,
<ls_object> LIKE LINE OF ct_objects.
lv_class = iv_obj_name.
cl_oo_classname_service=>get_all_method_includes(
EXPORTING
clsname = lv_class
RECEIVING
result = lt_methods
EXCEPTIONS
class_not_existing = 1
OTHERS = 2 ).
ASSERT sy-subrc = 0.
DELETE ct_objects WHERE object = 'METH'.
LOOP AT lt_methods ASSIGNING <ls_method>.
APPEND INITIAL LINE TO ct_objects ASSIGNING <ls_object>.
<ls_object>-object = 'METH'.
<ls_object>-obj_name = <ls_method>-incname.
ENDLOOP.
ENDMETHOD.
METHOD show_activation_errors.
DATA: lt_lines TYPE STANDARD TABLE OF trlog,
lv_logname_db TYPE ddprh-protname,
lo_log TYPE REF TO zcl_abapgit_log.
FIELD-SYMBOLS: <ls_line> LIKE LINE OF lt_lines.
lv_logname_db = iv_logname.
CALL FUNCTION 'TR_READ_LOG'
EXPORTING
iv_log_type = 'DB'
iv_logname_db = lv_logname_db
TABLES
et_lines = lt_lines
EXCEPTIONS
invalid_input = 1
access_error = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from TR_READ_LOG' ).
ENDIF.
DELETE lt_lines WHERE severity <> 'E'.
CREATE OBJECT lo_log.
LOOP AT lt_lines ASSIGNING <ls_line>.
lo_log->add( <ls_line>-line ).
ENDLOOP.
lo_log->show( ).
ENDMETHOD.
METHOD update_where_used.
DATA: lv_class LIKE LINE OF gt_classes,
lo_cross TYPE REF TO cl_wb_crossreference,
lv_include TYPE programm,
lo_progress TYPE REF TO zcl_abapgit_progress.
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( gt_classes ).
LOOP AT gt_classes INTO lv_class.
IF sy-tabix MOD 20 = 0.
lo_progress->show(
iv_current = sy-tabix
iv_text = 'Updating where-used lists' ).
ENDIF.
lv_include = cl_oo_classname_service=>get_classpool_name( lv_class ).
CREATE OBJECT lo_cross
EXPORTING
p_name = lv_include
p_include = lv_include.
lo_cross->index_actualize( ).
ENDLOOP.
ENDMETHOD.
METHOD use_new_activation_logic.
IF zcl_abapgit_persist_settings=>get_instance( )->read( )->get_experimental_features( ) = abap_true.
CALL FUNCTION 'FUNCTION_EXISTS'
EXPORTING
funcname = 'DD_MASS_ACT_C3' " Name of Function Module
EXCEPTIONS
function_not_exist = 1
OTHERS = 2.
IF sy-subrc = 0.
rv_use_new_activation_logic = abap_true.
ENDIF.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_xslt IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lo_xslt TYPE REF TO cl_o2_api_xsltdesc,
ls_attributes TYPE o2xsltattr.
lo_xslt = get( ).
lo_xslt->get_attributes(
RECEIVING
p_attributes = ls_attributes
EXCEPTIONS
object_invalid = 1
xsltdesc_deleted = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
rv_user = ls_attributes-changedby.
ENDMETHOD.
METHOD get.
DATA: lv_name TYPE cxsltdesc.
lv_name = ms_item-obj_name.
cl_o2_api_xsltdesc=>load(
EXPORTING
p_xslt_desc = lv_name
IMPORTING
p_obj = ro_xslt
EXCEPTIONS
not_existing = 1
permission_failure = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from cl_o2_api_xsltdesc=>load' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_xslt TYPE REF TO cl_o2_api_xsltdesc,
lv_source TYPE string,
ls_attributes TYPE o2xsltattr.
lo_xslt = get( ).
ls_attributes = lo_xslt->get_attributes( ).
CLEAR: ls_attributes-author,
ls_attributes-createdon,
ls_attributes-changedby,
ls_attributes-changedon,
ls_attributes-devclass.
io_xml->add( iv_name = 'ATTRIBUTES'
ig_data = ls_attributes ).
lv_source = lo_xslt->get_source_string( ).
mo_files->add_string( iv_extra = 'source'
iv_ext = 'xml'
iv_string = lv_source ) ##NO_TEXT.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_source TYPE string,
lo_xslt TYPE REF TO cl_o2_api_xsltdesc,
lv_len TYPE i,
ls_attributes TYPE o2xsltattr.
IF zif_abapgit_object~exists( ) = abap_true.
zif_abapgit_object~delete( ).
ENDIF.
io_xml->read( EXPORTING iv_name = 'ATTRIBUTES'
CHANGING cg_data = ls_attributes ).
ls_attributes-devclass = iv_package.
lv_source = mo_files->read_string( iv_extra = 'source'
iv_ext = 'xml' ) ##NO_TEXT.
lv_len = strlen( lv_source ) - 2.
IF lv_source+lv_len(2) = cl_abap_char_utilities=>cr_lf.
lv_source = lv_source(lv_len).
ENDIF.
cl_o2_api_xsltdesc=>create_new_from_string(
EXPORTING
p_source = lv_source
p_attr = ls_attributes
IMPORTING
p_obj = lo_xslt
EXCEPTIONS
action_cancelled = 1
error_occured = 2
not_authorized = 3
object_already_existing = 4
undefined_name = 5
OTHERS = 6 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from cl_o2_api_xsltdesc=>create_new_from_string' ).
ENDIF.
lo_xslt->activate( ).
lo_xslt->save( ).
lo_xslt->set_changeable( abap_false ).
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_xslt TYPE REF TO cl_o2_api_xsltdesc,
lv_name TYPE cxsltdesc.
lv_name = ms_item-obj_name.
cl_o2_api_xsltdesc=>load(
EXPORTING
p_xslt_desc = lv_name
IMPORTING
p_obj = lo_xslt
EXCEPTIONS
error_occured = 1
not_existing = 2
permission_failure = 3
version_not_found = 4
OTHERS = 5 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from cl_o2_api_xsltdesc=>load' ).
ENDIF.
lo_xslt->set_changeable( abap_true ).
lo_xslt->delete( ).
lo_xslt->save( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_name TYPE cxsltdesc.
lv_name = ms_item-obj_name.
rv_bool = cl_o2_api_xsltdesc=>exists( lv_name ).
IF rv_bool = '1'.
rv_bool = abap_true.
ELSE.
rv_bool = abap_false.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_xinx IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
cl_wb_object_type=>get_key_components_from_id(
EXPORTING
p_key = |{ ms_item-obj_name }|
p_external_id = swbm_c_type_ddic_db_tabxinx
IMPORTING
p_key_component1 = mv_name
p_key_component2 = mv_id
EXCEPTIONS
too_many_key_components = 1
objecttype_not_existing = 2
OTHERS = 3 ).
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
" RS_DD_INDX_DELETE calls the GUI. Someday we need a better solution
CALL FUNCTION 'RS_DD_INDX_DELETE'
EXPORTING
objname = mv_name
indexname = mv_id
extension = abap_true
EXCEPTIONS
object_not_found = 1
object_not_specified = 2
permission_failure = 3
action_cancelled = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from RS_DD_INDX_DELETE { sy-subrc }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_extension_index TYPE ty_extension_index,
rc TYPE sy-subrc.
io_xml->read(
EXPORTING
iv_name = 'XINX'
CHANGING
cg_data = ls_extension_index ).
tadir_insert( iv_package ).
CALL FUNCTION 'DDIF_INDX_PUT'
EXPORTING
name = mv_name
id = mv_id
dd12v_wa = ls_extension_index-dd12v
TABLES
dd17v_tab = ls_extension_index-t_dd17v
EXCEPTIONS
indx_not_found = 1
name_inconsistent = 2
indx_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from DDIF_INDX_PUT { sy-subrc }| ).
ENDIF.
CALL FUNCTION 'DDIF_INDX_ACTIVATE'
EXPORTING
name = mv_name
id = mv_id
IMPORTING
rc = rc
EXCEPTIONS
not_found = 1
put_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from DDIF_INDX_ACTIVATE { sy-subrc }| ).
ENDIF.
IF rc <> 0.
zcx_abapgit_exception=>raise( |Cannot activate extension index { mv_id } of table { mv_name }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_dd12v TYPE dd12v.
CALL FUNCTION 'DDIF_INDX_GET'
EXPORTING
name = mv_name
id = mv_id
IMPORTING
dd12v_wa = lv_dd12v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
rv_bool = boolc( lv_dd12v IS NOT INITIAL ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
in_new_window = abap_true
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from RS_TOOL_ACCESS { sy-subrc }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_extension_index TYPE ty_extension_index.
CALL FUNCTION 'DDIF_INDX_GET'
EXPORTING
name = mv_name
id = mv_id
langu = sy-langu
IMPORTING
dd12v_wa = ls_extension_index-dd12v
TABLES
dd17v_tab = ls_extension_index-t_dd17v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from DDIF_INDX_GET { sy-subrc }| ).
ENDIF.
CLEAR: ls_extension_index-dd12v-as4user,
ls_extension_index-dd12v-as4date,
ls_extension_index-dd12v-as4time.
io_xml->add( iv_name = 'XINX'
ig_data = ls_extension_index ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_WEBI IMPLEMENTATION.
METHOD handle_endpoint.
DATA: ls_endpoint LIKE LINE OF is_webi-pvependpoint,
li_endpoint TYPE REF TO if_ws_md_vif_endpoint_ref.
FIELD-SYMBOLS: <ls_function> LIKE LINE OF is_webi-pvepfunction.
READ TABLE is_webi-pvependpoint INDEX 1 INTO ls_endpoint.
ASSERT sy-subrc = 0.
IF mi_vi->has_endpoint_reference( sews_c_vif_version-all ) = abap_true.
RETURN.
ENDIF.
li_endpoint = mi_vi->create_endpoint_reference(
endpoint_type = ls_endpoint-endpointtype
service_def_startpoint = ls_endpoint-def_start_pt
auto_generated = ls_endpoint-auto_generated
i_is_srvv = ls_endpoint-is_srvv ).
IF ls_endpoint-endpointtype = 'BAPI'.
zcx_abapgit_exception=>raise( 'todo, WEBI BAPI' ).
ENDIF.
IF lines( is_webi-pvepfunction ) <> 1.
zcx_abapgit_exception=>raise( 'todo, WEBI, function name' ).
ENDIF.
READ TABLE is_webi-pvepfunction INDEX 1 ASSIGNING <ls_function>.
li_endpoint->set_data(
data_version = '1'
data = <ls_function>-function ).
ENDMETHOD.
METHOD handle_function.
CONSTANTS: BEGIN OF lc_parameter_type,
import TYPE vepparamtype VALUE 'I',
export TYPE vepparamtype VALUE 'O',
END OF lc_parameter_type.
DATA: li_parameter TYPE REF TO if_ws_md_vif_param,
li_soap TYPE REF TO if_ws_md_soap_ext_func,
li_fault TYPE REF TO if_ws_md_vif_fault,
li_function TYPE REF TO if_ws_md_vif_func.
FIELD-SYMBOLS: <ls_function> LIKE LINE OF is_webi-pvepfunction,
<ls_soap> LIKE LINE OF is_webi-pvepfuncsoapext,
<ls_fault> LIKE LINE OF is_webi-pvepfault,
<ls_parameter> LIKE LINE OF is_webi-pvepparameter.
LOOP AT is_webi-pvepfunction ASSIGNING <ls_function>.
IF mi_vi->has_function( funcname = <ls_function>-function
version = sews_c_vif_version-active ) = abap_true.
CONTINUE.
ENDIF.
li_function = mi_vi->create_function(
funcname = <ls_function>-function
mapped_name = <ls_function>-mappedname ).
li_function->set_is_exposed( <ls_function>-is_exposed ).
LOOP AT is_webi-pvepparameter ASSIGNING <ls_parameter>
WHERE function = <ls_function>-function.
CASE <ls_parameter>-vepparamtype.
WHEN lc_parameter_type-import.
li_parameter = li_function->create_incoming_parameter(
<ls_parameter>-vepparam ).
WHEN lc_parameter_type-export.
li_parameter = li_function->create_outgoing_parameter(
<ls_parameter>-vepparam ).
WHEN OTHERS.
ASSERT 0 = 1.
ENDCASE.
li_parameter->set_name_mapped_to( <ls_parameter>-mappedname ).
li_parameter->set_is_exposed( <ls_parameter>-is_exposed ).
li_parameter->set_is_optional( <ls_parameter>-is_optional ).
li_parameter->set_default_value( <ls_parameter>-default_value ).
li_parameter->set_initial( <ls_parameter>-is_initial ).
li_parameter->set_type( <ls_parameter>-typename ).
ENDLOOP.
LOOP AT is_webi-pvepfuncsoapext ASSIGNING <ls_soap>
WHERE function = <ls_function>-function.
li_soap = li_function->create_soap_extension_function( ).
li_soap->set_soap_request_name( <ls_soap>-requestname ).
li_soap->set_soap_response_name( <ls_soap>-responsename ).
li_soap->set_namespace( <ls_soap>-namespace ).
ENDLOOP.
LOOP AT is_webi-pvepfault ASSIGNING <ls_fault>
WHERE function = <ls_function>-function.
li_fault = li_function->create_fault( <ls_fault>-fault ).
li_fault->set_name_mapped_to( <ls_fault>-mappedname ).
li_fault->set_detail( <ls_fault>-detail ).
ENDLOOP.
ENDLOOP.
ENDMETHOD.
METHOD handle_soap.
DATA: li_soap TYPE REF TO if_ws_md_soap_ext_virtinfc,
ls_soap LIKE LINE OF is_webi-pvepvisoapext.
READ TABLE is_webi-pvepvisoapext INDEX 1 INTO ls_soap.
ASSERT sy-subrc = 0.
IF mi_vi->has_soap_extension_virtinfc( sews_c_vif_version-active ) = abap_true.
RETURN.
ENDIF.
li_soap = mi_vi->create_soap_extension_virtinfc( ls_soap-soap_appl_uri ).
li_soap->set_namespace( ls_soap-namespace ).
ENDMETHOD.
METHOD handle_types.
DATA: lv_index TYPE i,
li_soap TYPE REF TO if_ws_md_soap_extension_type,
li_struc TYPE REF TO if_ws_md_vif_struc_type,
li_field TYPE REF TO if_ws_md_vif_field,
li_table TYPE REF TO if_ws_md_vif_table_type,
li_elem TYPE REF TO if_ws_md_vif_elem_type.
FIELD-SYMBOLS: <ls_elem> LIKE LINE OF is_webi-pvepelemtype,
<ls_table> LIKE LINE OF is_webi-pveptabletype,
<ls_soap> LIKE LINE OF is_webi-pveptypesoapext,
<ls_struc> LIKE LINE OF is_webi-pvepstrutype.
LOOP AT is_webi-pvepelemtype ASSIGNING <ls_elem>.
li_elem = mi_vi->create_type_as_elementary( <ls_elem>-typename ).
li_elem->set_built_in_type( <ls_elem>-build_in_type ).
li_elem->set_decimals( <ls_elem>-decimals ).
li_elem->set_kind( <ls_elem>-kind ).
li_elem->set_length( <ls_elem>-length ).
li_elem->set_signed( <ls_elem>-signed ).
li_elem->set_abaptype( <ls_elem>-abaptype ).
IF li_elem->if_ws_md_vif_type~has_soap_extension_type(
sews_c_vif_version-all ) = abap_false.
READ TABLE is_webi-pveptypesoapext ASSIGNING <ls_soap>
WITH KEY typename = <ls_elem>-typename.
IF sy-subrc = 0.
li_soap = li_elem->if_ws_md_vif_type~create_soap_extension_type( ).
li_soap->set_namespace( <ls_soap>-namespace ).
ENDIF.
ENDIF.
ENDLOOP.
LOOP AT is_webi-pvepstrutype ASSIGNING <ls_struc>.
lv_index = sy-tabix.
li_struc = mi_vi->create_type_as_structure( <ls_struc>-typename ).
IF li_struc->has_field( field_pos = <ls_struc>-fieldpos
version = sews_c_vif_version-active ) = abap_true.
CONTINUE.
ENDIF.
li_field = li_struc->create_field(
field_name = <ls_struc>-fieldname
fieldpos = <ls_struc>-fieldpos ).
li_field->set_type( mi_vi->get_type( typename = <ls_struc>-typeref
version = sews_c_vif_version-inactive ) ).
IF lv_index = 1
AND li_struc->if_ws_md_vif_type~has_soap_extension_type(
sews_c_vif_version-all ) = abap_false.
READ TABLE is_webi-pveptypesoapext ASSIGNING <ls_soap>
WITH KEY typename = <ls_struc>-typename.
IF sy-subrc = 0.
li_soap = li_struc->if_ws_md_vif_type~create_soap_extension_type( ).
li_soap->set_namespace( <ls_soap>-namespace ).
ENDIF.
ENDIF.
ENDLOOP.
LOOP AT is_webi-pveptabletype ASSIGNING <ls_table>.
li_table = mi_vi->create_type_as_table( <ls_table>-typename ).
li_table->set_line_type( mi_vi->get_type( typename = <ls_table>-typeref
version = sews_c_vif_version-inactive ) ).
IF li_table->if_ws_md_vif_type~has_soap_extension_type(
sews_c_vif_version-all ) = abap_false.
READ TABLE is_webi-pveptypesoapext ASSIGNING <ls_soap>
WITH KEY typename = <ls_table>-typename.
IF sy-subrc = 0.
li_soap = li_table->if_ws_md_vif_type~create_soap_extension_type( ).
li_soap->set_namespace( <ls_soap>-namespace ).
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_name TYPE vepname,
lo_vif TYPE REF TO cl_ws_md_vif_root.
lv_name = ms_item-obj_name.
CREATE OBJECT lo_vif.
TRY.
lo_vif->if_ws_md_vif_root~delete_virtual_interface( lv_name ).
CATCH cx_ws_md_exception.
zcx_abapgit_exception=>raise( 'error deleting WEBI' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_webi TYPE ty_webi,
lv_name TYPE vepname,
ls_header LIKE LINE OF ls_webi-pvepheader,
lv_text TYPE string ##needed,
lx_root TYPE REF TO cx_root,
lv_exists TYPE abap_bool,
li_root TYPE REF TO if_ws_md_vif_root.
io_xml->read( EXPORTING iv_name = 'WEBI'
CHANGING cg_data = ls_webi ).
lv_name = ms_item-obj_name.
READ TABLE ls_webi-pvepheader INDEX 1 INTO ls_header.
ASSERT sy-subrc = 0.
lv_exists = cl_ws_md_vif_root=>check_existence_by_vif_name(
name = lv_name
i_version = sews_c_vif_version-all ).
li_root = cl_ws_md_factory=>get_vif_root( ).
TRY.
IF lv_exists = abap_false.
mi_vi = li_root->create_virtual_interface(
name = lv_name
nameext = ls_header-vepnameext ).
ELSE.
mi_vi = li_root->get_virtual_interface( lv_name ).
mi_vi->if_ws_md_lockable_object~lock( ).
ENDIF.
mi_vi->set_short_text( ls_webi-veptext ).
handle_endpoint( ls_webi ).
handle_types( ls_webi ).
handle_function( ls_webi ).
handle_soap( ls_webi ).
mi_vi->if_ws_md_lockable_object~save( ).
mi_vi->if_ws_md_lockable_object~unlock( ).
CATCH cx_ws_md_exception INTO lx_root.
TRY.
mi_vi->if_ws_md_lockable_object~unlock( ).
CATCH cx_ws_md_exception ##no_handler.
ENDTRY.
lv_text = lx_root->if_message~get_text( ).
zcx_abapgit_exception=>raise( 'error deserializing WEBI' ).
ENDTRY.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_name TYPE vepname.
lv_name = ms_item-obj_name.
rv_bool = cl_ws_md_vif_root=>check_existence_by_vif_name(
name = lv_name
i_version = sews_c_vif_version-active ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_webi TYPE ty_webi,
lt_modilog TYPE STANDARD TABLE OF smodilog WITH DEFAULT KEY,
li_vi TYPE REF TO if_ws_md_vif,
lv_name TYPE vepname.
FIELD-SYMBOLS: <ls_header> LIKE LINE OF ls_webi-pvepheader,
<ls_endpoint> LIKE LINE OF ls_webi-pvependpoint.
CALL FUNCTION 'WEBI_GET_OBJECT'
EXPORTING
webiname = ms_item-obj_name
TABLES
psmodilog = lt_modilog
pvepheader = ls_webi-pvepheader
pvepfunction = ls_webi-pvepfunction
pvepfault = ls_webi-pvepfault
pvepparameter = ls_webi-pvepparameter
pveptype = ls_webi-pveptype
pvepelemtype = ls_webi-pvepelemtype
pveptabletype = ls_webi-pveptabletype
pvepstrutype = ls_webi-pvepstrutype
pveptypesoapext = ls_webi-pveptypesoapext
pvepeletypsoap = ls_webi-pvepeletypsoap
pveptabtypsoap = ls_webi-pveptabtypsoap
pvepfuncsoapext = ls_webi-pvepfuncsoapext
pvepfieldref = ls_webi-pvepfieldref
pvependpoint = ls_webi-pvependpoint
pvepvisoapext = ls_webi-pvepvisoapext
pvepparasoapext = ls_webi-pvepparasoapext
EXCEPTIONS
version_not_found = 1
webi_not_exist = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from WEBI_GET_OBJECT' ).
ENDIF.
SORT ls_webi-pveptype BY
vepname ASCENDING
version ASCENDING
typename ASCENDING.
lv_name = ms_item-obj_name.
TRY.
li_vi = cl_ws_md_factory=>get_vif_root( )->get_virtual_interface( lv_name ).
ls_webi-veptext = li_vi->get_short_text( sews_c_vif_version-active ).
CATCH cx_ws_md_exception.
zcx_abapgit_exception=>raise( 'error serializing WEBI' ).
ENDTRY.
LOOP AT ls_webi-pvepheader ASSIGNING <ls_header>.
CLEAR <ls_header>-author.
CLEAR <ls_header>-createdon.
CLEAR <ls_header>-changedby.
CLEAR <ls_header>-changedon.
CLEAR <ls_header>-ctime.
CLEAR <ls_header>-text_id.
CLEAR <ls_header>-utime.
CLEAR <ls_header>-wsint_version.
ENDLOOP.
LOOP AT ls_webi-pvependpoint ASSIGNING <ls_endpoint>.
CLEAR: <ls_endpoint>-clustd.
ENDLOOP.
io_xml->add( iv_name = 'WEBI'
ig_data = ls_webi ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_WDYN IMPLEMENTATION.
METHOD add_fm_exception.
DATA: ls_exception LIKE LINE OF ct_exception.
ls_exception-name = iv_name.
ls_exception-value = iv_value.
INSERT ls_exception INTO TABLE ct_exception.
ENDMETHOD.
METHOD add_fm_param_exporting.
DATA: ls_param LIKE LINE OF ct_param.
ls_param-kind = abap_func_exporting.
ls_param-name = iv_name.
GET REFERENCE OF ig_value INTO ls_param-value.
INSERT ls_param INTO TABLE ct_param.
ENDMETHOD.
METHOD add_fm_param_tables.
DATA: ls_param LIKE LINE OF ct_param.
ls_param-kind = abap_func_tables.
ls_param-name = iv_name.
GET REFERENCE OF ct_value INTO ls_param-value.
INSERT ls_param INTO TABLE ct_param.
ENDMETHOD.
METHOD delta_controller.
DATA: li_controller TYPE REF TO if_wdy_md_controller,
lv_found TYPE abap_bool,
ls_key TYPE wdy_md_controller_key,
ls_obj_new TYPE svrs2_versionable_object,
ls_obj_old TYPE svrs2_versionable_object.
FIELD-SYMBOLS: <ls_component> LIKE LINE OF mt_components,
<ls_source> LIKE LINE OF mt_sources,
<lt_ctrl_exceptions> TYPE ANY TABLE,
<lt_ctrl_exception_texts> TYPE ANY TABLE,
<lt_excp> TYPE ANY TABLE,
<lt_excpt> TYPE ANY TABLE.
ls_key-component_name = is_controller-definition-component_name.
ls_key-controller_name = is_controller-definition-controller_name.
lv_found = cl_wdy_md_controller=>check_existency(
component_name = ls_key-component_name
controller_name = ls_key-controller_name ).
IF lv_found = abap_false.
TRY.
li_controller ?= cl_wdy_md_controller=>create_complete(
component_name = ls_key-component_name
controller_name = ls_key-controller_name
controller_type = is_controller-definition-controller_type ).
li_controller->save_to_database( ).
li_controller->unlock( ).
CATCH cx_wdy_md_exception.
zcx_abapgit_exception=>raise( 'error creating dummy controller' ).
ENDTRY.
ENDIF.
ls_obj_new-objtype = wdyn_limu_component_controller.
ls_obj_new-objname = ls_key.
ls_obj_old-objtype = wdyn_limu_component_controller.
ls_obj_old-objname = ls_key.
APPEND is_controller-definition TO ls_obj_old-wdyc-defin.
LOOP AT mt_components ASSIGNING <ls_component>
WHERE component_name = ls_key-component_name
AND controller_name = ls_key-controller_name.
APPEND <ls_component> TO ls_obj_old-wdyc-ccomp.
ENDLOOP.
LOOP AT mt_sources ASSIGNING <ls_source>
WHERE component_name = ls_key-component_name
AND controller_name = ls_key-controller_name.
APPEND <ls_source> TO ls_obj_old-wdyc-ccoms.
ENDLOOP.
ls_obj_old-wdyc-descr = is_controller-descriptions.
ls_obj_old-wdyc-cusag = is_controller-controller_usages.
ls_obj_old-wdyc-ccomt = is_controller-controller_component_texts.
ls_obj_old-wdyc-cpara = is_controller-controller_parameters.
ls_obj_old-wdyc-cpart = is_controller-controller_parameter_texts.
ls_obj_old-wdyc-cnode = is_controller-context_nodes.
ls_obj_old-wdyc-cattr = is_controller-context_attributes.
ls_obj_old-wdyc-cmapp = is_controller-context_mappings.
ASSIGN COMPONENT 'CONTROLLER_EXCEPTIONS' OF STRUCTURE is_controller
TO <lt_ctrl_exceptions>.
IF sy-subrc = 0.
ASSIGN COMPONENT 'EXCP' OF STRUCTURE ls_obj_old-wdyc TO <lt_excp>.
IF sy-subrc = 0.
<lt_excp> = <lt_ctrl_exceptions>.
ENDIF.
ENDIF.
ASSIGN COMPONENT 'CONTROLLER_EXCEPTIONS_TEXTS' OF STRUCTURE is_controller
TO <lt_ctrl_exception_texts>.
IF sy-subrc = 0.
ASSIGN COMPONENT 'EXCPT' OF STRUCTURE ls_obj_old-wdyc TO <lt_excpt>.
IF sy-subrc = 0.
<lt_excpt> = <lt_ctrl_exception_texts>.
ENDIF.
ENDIF.
ls_obj_old-wdyc-fgrps = is_controller-fieldgroups.
CALL FUNCTION 'SVRS_MAKE_OBJECT_DELTA'
EXPORTING
obj_old = ls_obj_new
obj_new = ls_obj_old
CHANGING
delta = rs_delta
EXCEPTIONS
inconsistent_objects = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SVRS_MAKE_OBJECT_DELTA' ).
ENDIF.
ENDMETHOD.
METHOD delta_definition.
DATA: ls_key TYPE wdy_md_component_key,
lv_found TYPE abap_bool,
ls_obj_new TYPE svrs2_versionable_object,
li_component TYPE REF TO if_wdy_md_component,
ls_obj_old TYPE svrs2_versionable_object.
ls_key-component_name = is_definition-definition-component_name.
lv_found = cl_wdy_md_component=>check_existency( ls_key-component_name ).
IF lv_found = abap_false.
TRY.
cl_wdy_md_component=>create_complete(
EXPORTING
name = ls_key-component_name
IMPORTING
component = li_component
CHANGING
devclass = iv_package ).
li_component->save_to_database( ).
li_component->unlock( ).
CATCH cx_wdy_md_exception.
zcx_abapgit_exception=>raise( 'error creating dummy component' ).
ENDTRY.
ENDIF.
ls_obj_new-objtype = wdyn_limu_component_definition.
ls_obj_new-objname = ls_key-component_name.
ls_obj_old-objtype = wdyn_limu_component_definition.
ls_obj_old-objname = ls_key-component_name.
APPEND is_definition-definition TO ls_obj_old-wdyd-defin.
ls_obj_old-wdyd-descr = is_definition-descriptions.
ls_obj_old-wdyd-cusag = is_definition-component_usages.
ls_obj_old-wdyd-intrf = is_definition-interface_implementings.
ls_obj_old-wdyd-libra = is_definition-library_usages.
ls_obj_old-wdyd-ctuse = is_definition-ext_ctlr_usages.
ls_obj_old-wdyd-ctmap = is_definition-ext_ctx_mappings.
CALL FUNCTION 'SVRS_MAKE_OBJECT_DELTA'
EXPORTING
obj_old = ls_obj_new
obj_new = ls_obj_old
CHANGING
delta = rs_delta
EXCEPTIONS
inconsistent_objects = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SVRS_MAKE_OBJECT_DELTA' ).
ENDIF.
ENDMETHOD.
METHOD delta_view.
DATA: ls_key TYPE wdy_md_view_key,
ls_obj_new TYPE svrs2_versionable_object,
ls_obj_old TYPE svrs2_versionable_object,
lv_found TYPE abap_bool,
li_view TYPE REF TO if_wdy_md_abstract_view.
FIELD-SYMBOLS: <ls_def> LIKE LINE OF ls_obj_old-wdyv-defin.
ls_key-component_name = is_view-definition-component_name.
ls_key-view_name = is_view-definition-view_name.
lv_found = cl_wdy_md_abstract_view=>check_existency(
component_name = ls_key-component_name
name = ls_key-view_name ).
IF lv_found = abap_false.
TRY.
li_view = cl_wdy_md_abstract_view=>create(
component_name = is_view-definition-component_name
view_name = is_view-definition-view_name
type = is_view-definition-type ).
li_view->save_to_database( ).
li_view->unlock( ).
CATCH cx_wdy_md_exception.
zcx_abapgit_exception=>raise( 'error creating dummy view' ).
ENDTRY.
ENDIF.
ls_obj_new-objtype = wdyn_limu_component_view.
ls_obj_new-objname = ls_key.
ls_obj_old-objtype = wdyn_limu_component_view.
ls_obj_old-objname = ls_key.
APPEND INITIAL LINE TO ls_obj_old-wdyv-defin ASSIGNING <ls_def>.
MOVE-CORRESPONDING is_view-definition TO <ls_def>.
ls_obj_old-wdyv-descr = is_view-descriptions.
ls_obj_old-wdyv-vcont = is_view-view_containers.
ls_obj_old-wdyv-vcntt = is_view-view_container_texts.
ls_obj_old-wdyv-ibplg = is_view-iobound_plugs.
ls_obj_old-wdyv-ibplt = is_view-iobound_plug_texts.
ls_obj_old-wdyv-plpar = is_view-plug_parameters.
ls_obj_old-wdyv-plprt = is_view-plug_parameter_texts.
ls_obj_old-wdyv-uiele = is_view-ui_elements.
ls_obj_old-wdyv-uicon = is_view-ui_context_bindings.
ls_obj_old-wdyv-uievt = is_view-ui_event_bindings.
ls_obj_old-wdyv-uiddc = is_view-ui_ddic_bindings.
ls_obj_old-wdyv-uiprp = is_view-ui_properties.
ls_obj_old-wdyv-navil = is_view-navigation_links.
ls_obj_old-wdyv-navit = is_view-navigation_target_refs.
ls_obj_old-wdyv-vshno = is_view-vsh_nodes.
ls_obj_old-wdyv-vshpl = is_view-vsh_placeholders.
ls_obj_old-wdyv-views = is_view-viewset_properties.
CALL FUNCTION 'SVRS_MAKE_OBJECT_DELTA'
EXPORTING
obj_old = ls_obj_new
obj_new = ls_obj_old
CHANGING
delta = rs_delta
EXCEPTIONS
inconsistent_objects = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SVRS_MAKE_OBJECT_DELTA' ).
ENDIF.
ENDMETHOD.
METHOD get_limu_objects.
DATA: lv_name TYPE wdy_component_name.
lv_name = ms_item-obj_name.
CALL FUNCTION 'WDYN_GET_LIMU_OBJECTS'
EXPORTING
component_name = lv_name
IMPORTING
limu_objects = rt_objects.
ENDMETHOD.
METHOD read.
DATA: lt_objects TYPE wdy_md_transport_keys,
ls_controller_key TYPE wdy_md_controller_key,
ls_component_key TYPE wdy_md_component_key,
ls_view_key TYPE wdy_md_view_key.
FIELD-SYMBOLS: <ls_object> LIKE LINE OF lt_objects,
<ls_meta> LIKE LINE OF rs_component-ctlr_metadata,
<lt_ctrl_exceptions> TYPE ANY TABLE,
<lt_ctrl_exception_texts> TYPE ANY TABLE.
CLEAR mt_components.
CLEAR mt_sources.
lt_objects = get_limu_objects( ).
LOOP AT lt_objects ASSIGNING <ls_object>.
CASE <ls_object>-sub_type.
WHEN wdyn_limu_component_controller.
ls_controller_key = <ls_object>-sub_name.
APPEND read_controller( ls_controller_key ) TO rs_component-ctlr_metadata.
WHEN wdyn_limu_component_definition.
ls_component_key = <ls_object>-sub_name.
rs_component-comp_metadata = read_definition( ls_component_key ).
WHEN wdyn_limu_component_view.
ls_view_key = <ls_object>-sub_name.
APPEND read_view( ls_view_key ) TO rs_component-view_metadata.
WHEN OTHERS.
ASSERT 0 = 1.
ENDCASE.
ENDLOOP.
SORT rs_component-ctlr_metadata BY
definition-component_name ASCENDING
definition-controller_name ASCENDING.
LOOP AT rs_component-ctlr_metadata ASSIGNING <ls_meta>.
SORT <ls_meta>-descriptions.
SORT <ls_meta>-controller_usages.
SORT <ls_meta>-controller_components.
SORT <ls_meta>-controller_component_texts.
SORT <ls_meta>-controller_parameters.
SORT <ls_meta>-controller_parameter_texts.
SORT <ls_meta>-context_nodes.
SORT <ls_meta>-context_attributes.
SORT <ls_meta>-context_mappings.
SORT <ls_meta>-fieldgroups.
ASSIGN COMPONENT 'CONTROLLER_EXCEPTIONS' OF STRUCTURE <ls_meta> TO <lt_ctrl_exceptions>.
IF sy-subrc = 0.
SORT <lt_ctrl_exceptions>.
ENDIF.
ASSIGN COMPONENT 'CONTROLLER_EXCEPTION_TEXTS' OF STRUCTURE <ls_meta> TO <lt_ctrl_exception_texts>.
IF sy-subrc = 0.
SORT <lt_ctrl_exception_texts>.
ENDIF.
ENDLOOP.
SORT mt_components BY
component_name ASCENDING
controller_name ASCENDING
cmpname ASCENDING.
SORT mt_sources BY
component_name ASCENDING
controller_name ASCENDING
cmpname ASCENDING
line_number ASCENDING.
ENDMETHOD.
METHOD read_controller.
DATA: lt_components TYPE TABLE OF wdy_ctlr_compo_vrs,
lt_sources TYPE TABLE OF wdy_ctlr_compo_source_vrs,
lt_definition TYPE TABLE OF wdy_controller,
lt_psmodilog TYPE TABLE OF smodilog,
lt_psmodisrc TYPE TABLE OF smodisrc,
lt_fm_param TYPE abap_func_parmbind_tab,
lt_fm_exception TYPE abap_func_excpbind_tab.
FIELD-SYMBOLS: <lt_ctrl_exceptions> TYPE ANY TABLE,
<lt_ctrl_exception_texts> TYPE ANY TABLE.
add_fm_param_exporting( EXPORTING iv_name = 'CONTROLLER_KEY'
ig_value = is_key
CHANGING ct_param = lt_fm_param ).
add_fm_param_exporting( EXPORTING iv_name = 'GET_ALL_TRANSLATIONS'
ig_value = abap_false
CHANGING ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'DEFINITION'
CHANGING ct_value = lt_definition
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'DESCRIPTIONS'
CHANGING ct_value = rs_controller-descriptions
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTROLLER_USAGES'
CHANGING ct_value = rs_controller-controller_usages
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTROLLER_COMPONENTS'
CHANGING ct_value = lt_components
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTROLLER_COMPONENT_SOURCES'
CHANGING ct_value = lt_sources
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTROLLER_COMPONENT_TEXTS'
CHANGING ct_value = rs_controller-controller_component_texts
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTROLLER_PARAMETERS'
CHANGING ct_value = rs_controller-controller_parameters
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTROLLER_PARAMETER_TEXTS'
CHANGING ct_value = rs_controller-controller_parameter_texts
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTEXT_NODES'
CHANGING ct_value = rs_controller-context_nodes
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTEXT_ATTRIBUTES'
CHANGING ct_value = rs_controller-context_attributes
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'CONTEXT_MAPPINGS'
CHANGING ct_value = rs_controller-context_mappings
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'FIELDGROUPS'
CHANGING ct_value = rs_controller-fieldgroups
ct_param = lt_fm_param ).
ASSIGN COMPONENT 'CONTROLLER_EXCEPTIONS' OF STRUCTURE rs_controller TO <lt_ctrl_exceptions>.
IF sy-subrc = 0.
add_fm_param_tables( EXPORTING iv_name = 'CONTROLLER_EXCEPTIONS'
CHANGING ct_value = <lt_ctrl_exceptions>
ct_param = lt_fm_param ).
ENDIF.
ASSIGN COMPONENT 'CONTROLLER_EXCEPTION_TEXTS' OF STRUCTURE rs_controller TO <lt_ctrl_exception_texts>.
IF sy-subrc = 0.
add_fm_param_tables( EXPORTING iv_name = 'CONTROLLER_EXCEPTION_TEXTS'
CHANGING ct_value = <lt_ctrl_exception_texts>
ct_param = lt_fm_param ).
ENDIF.
add_fm_param_tables( EXPORTING iv_name = 'PSMODILOG'
CHANGING ct_value = lt_psmodilog
ct_param = lt_fm_param ).
add_fm_param_tables( EXPORTING iv_name = 'PSMODISRC'
CHANGING ct_value = lt_psmodisrc
ct_param = lt_fm_param ).
add_fm_exception( EXPORTING iv_name = 'NOT_EXISTING'
iv_value = 1
CHANGING ct_exception = lt_fm_exception ).
add_fm_exception( EXPORTING iv_name = 'OTHERS'
iv_value = 2
CHANGING ct_exception = lt_fm_exception ).
CALL FUNCTION 'WDYC_GET_OBJECT'
PARAMETER-TABLE
lt_fm_param
EXCEPTION-TABLE
lt_fm_exception.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from WDYC_GET_OBJECT' ).
ENDIF.
APPEND LINES OF lt_components TO mt_components.
APPEND LINES OF lt_sources TO mt_sources.
READ TABLE lt_definition INDEX 1 INTO rs_controller-definition.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'WDYC, definition not found' ).
ENDIF.
CLEAR: rs_controller-definition-author,
rs_controller-definition-createdon,
rs_controller-definition-changedby,
rs_controller-definition-changedon.
ENDMETHOD.
METHOD read_definition.
DATA: lt_definition TYPE TABLE OF wdy_component,
lt_psmodilog TYPE TABLE OF smodilog,
lt_psmodisrc TYPE TABLE OF smodisrc.
CALL FUNCTION 'WDYD_GET_OBJECT'
EXPORTING
component_key = is_key
get_all_translations = abap_false
TABLES
definition = lt_definition
descriptions = rs_definition-descriptions
component_usages = rs_definition-component_usages
interface_implementings = rs_definition-interface_implementings
library_usages = rs_definition-library_usages
ext_ctlr_usages = rs_definition-ext_ctlr_usages
ext_ctx_mappings = rs_definition-ext_ctx_mappings
psmodilog = lt_psmodilog " not optional in all versions
psmodisrc = lt_psmodisrc " not optional in all versions
EXCEPTIONS
not_existing = 1
OTHERS = 2.
IF sy-subrc = 1.
RETURN.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from WDYD_GET_OBJECT' ).
ENDIF.
READ TABLE lt_definition INDEX 1 INTO rs_definition-definition.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'WDYD, definition not found' ).
ENDIF.
CLEAR: rs_definition-definition-author,
rs_definition-definition-createdon,
rs_definition-definition-changedby,
rs_definition-definition-changedon,
rs_definition-definition-gendate,
rs_definition-definition-gentime.
ENDMETHOD.
METHOD read_view.
DATA: lt_definition TYPE TABLE OF wdy_view_vrs,
lt_psmodilog TYPE TABLE OF smodilog,
lt_psmodisrc TYPE TABLE OF smodisrc.
FIELD-SYMBOLS: <ls_definition> LIKE LINE OF lt_definition.
CALL FUNCTION 'WDYV_GET_OBJECT'
EXPORTING
view_key = is_key
get_all_translations = abap_false
TABLES
definition = lt_definition
descriptions = rs_view-descriptions
view_containers = rs_view-view_containers
view_container_texts = rs_view-view_container_texts
iobound_plugs = rs_view-iobound_plugs
iobound_plug_texts = rs_view-iobound_plug_texts
plug_parameters = rs_view-plug_parameters
plug_parameter_texts = rs_view-plug_parameter_texts
ui_elements = rs_view-ui_elements
ui_context_bindings = rs_view-ui_context_bindings
ui_event_bindings = rs_view-ui_event_bindings
ui_ddic_bindings = rs_view-ui_ddic_bindings
ui_properties = rs_view-ui_properties
navigation_links = rs_view-navigation_links
navigation_target_refs = rs_view-navigation_target_refs
vsh_nodes = rs_view-vsh_nodes
vsh_placeholders = rs_view-vsh_placeholders
viewset_properties = rs_view-viewset_properties
psmodilog = lt_psmodilog
psmodisrc = lt_psmodisrc
EXCEPTIONS
not_existing = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from WDYV_GET_OBJECT' ).
ENDIF.
READ TABLE lt_definition INDEX 1 ASSIGNING <ls_definition>.
ASSERT sy-subrc = 0.
MOVE-CORRESPONDING <ls_definition> TO rs_view-definition.
CLEAR: rs_view-definition-author,
rs_view-definition-createdon,
rs_view-definition-changedby,
rs_view-definition-changedon.
ENDMETHOD.
METHOD recover_controller.
DATA: ls_key TYPE wdy_controller_key,
lv_corrnr TYPE trkorr,
ls_delta TYPE svrs2_xversionable_object.
ls_delta = delta_controller( is_controller ).
ls_key-component_name = is_controller-definition-component_name.
ls_key-controller_name = is_controller-definition-controller_name.
cl_wdy_md_controller=>recover_version(
EXPORTING
controller_key = ls_key
delta = ls_delta-wdyc
CHANGING
corrnr = lv_corrnr ).
ENDMETHOD.
METHOD recover_definition.
DATA: ls_key TYPE wdy_md_component_key,
lv_corrnr TYPE trkorr,
ls_delta TYPE svrs2_xversionable_object.
ls_delta = delta_definition(
is_definition = is_definition
iv_package = iv_package ).
ls_key-component_name = is_definition-definition-component_name.
cl_wdy_md_component=>recover_version(
EXPORTING
component_key = ls_key
delta = ls_delta-wdyd
CHANGING
corrnr = lv_corrnr ).
ENDMETHOD.
METHOD recover_view.
DATA: ls_key TYPE wdy_md_view_key,
lv_corrnr TYPE trkorr,
ls_delta TYPE svrs2_xversionable_object.
ls_delta = delta_view( is_view ).
ls_key-component_name = is_view-definition-component_name.
ls_key-view_name = is_view-definition-view_name.
cl_wdy_md_abstract_view=>recover_version(
EXPORTING
view_key = ls_key
delta = ls_delta-wdyv
CHANGING
corrnr = lv_corrnr ).
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_component TYPE REF TO cl_wdy_wb_component,
lo_request TYPE REF TO cl_wb_request,
li_state TYPE REF TO if_wb_program_state,
lv_object_name TYPE seu_objkey.
CREATE OBJECT lo_component.
lv_object_name = ms_item-obj_name.
CREATE OBJECT lo_request
EXPORTING
p_object_type = 'YC'
p_object_name = lv_object_name
p_operation = swbm_c_op_delete_no_dialog.
lo_component->if_wb_program~process_wb_request(
p_wb_request = lo_request
p_wb_program_state = li_state ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_component TYPE wdy_component_metadata.
FIELD-SYMBOLS: <ls_view> LIKE LINE OF ls_component-view_metadata,
<ls_controller> LIKE LINE OF ls_component-ctlr_metadata.
io_xml->read( EXPORTING iv_name = 'COMPONENT'
CHANGING cg_data = ls_component ).
io_xml->read( EXPORTING iv_name = 'COMPONENTS'
CHANGING cg_data = mt_components ).
io_xml->read( EXPORTING iv_name = 'SOURCES'
CHANGING cg_data = mt_sources ).
ls_component-comp_metadata-definition-author = sy-uname.
ls_component-comp_metadata-definition-createdon = sy-datum.
recover_definition( is_definition = ls_component-comp_metadata
iv_package = iv_package ).
LOOP AT ls_component-ctlr_metadata ASSIGNING <ls_controller>.
<ls_controller>-definition-author = sy-uname.
<ls_controller>-definition-createdon = sy-datum.
recover_controller( <ls_controller> ).
ENDLOOP.
LOOP AT ls_component-view_metadata ASSIGNING <ls_view>.
<ls_view>-definition-author = sy-uname.
<ls_view>-definition-createdon = sy-datum.
recover_view( <ls_view> ).
ENDLOOP.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_component_name TYPE wdy_component-component_name.
SELECT SINGLE component_name FROM wdy_component
INTO lv_component_name
WHERE component_name = ms_item-obj_name
AND version = 'A'. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_component TYPE wdy_component_metadata.
ls_component = read( ).
io_xml->add( iv_name = 'COMPONENT'
ig_data = ls_component ).
io_xml->add( ig_data = mt_components
iv_name = 'COMPONENTS' ).
io_xml->add( ig_data = mt_sources
iv_name = 'SOURCES' ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_wdya IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: li_app TYPE REF TO if_wdy_md_application,
ls_app TYPE wdy_application,
lv_name TYPE wdy_application_name.
lv_name = ms_item-obj_name.
TRY.
li_app = cl_wdy_md_application=>get_object_by_key(
name = lv_name
version = 'A' ).
li_app->if_wdy_md_object~get_definition( IMPORTING definition = ls_app ).
IF ls_app-changedby IS INITIAL.
rv_user = ls_app-author.
ELSE.
rv_user = ls_app-changedby.
ENDIF.
CATCH cx_root.
rv_user = c_user_unknown.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_name TYPE wdy_application_name.
lv_name = ms_item-obj_name.
TRY.
cl_wdy_md_application=>get_object_by_key(
name = lv_name
version = 'A' ).
rv_bool = abap_true.
CATCH cx_wdy_md_not_existing.
rv_bool = abap_false.
CATCH cx_wdy_md_permission_failure.
zcx_abapgit_exception=>raise( 'WDYA, permission failure' ).
ENDTRY.
ENDMETHOD.
METHOD read.
DATA: li_app TYPE REF TO if_wdy_md_application,
li_map TYPE REF TO if_object_map,
lo_prop TYPE REF TO cl_wdy_md_application_property,
ls_prop LIKE LINE OF et_properties,
lv_name TYPE wdy_application_name.
CLEAR es_app.
CLEAR et_properties.
lv_name = ms_item-obj_name.
TRY.
li_app = cl_wdy_md_application=>get_object_by_key(
name = lv_name
version = 'A' ).
CATCH cx_wdy_md_not_existing.
RETURN.
CATCH cx_wdy_md_permission_failure.
zcx_abapgit_exception=>raise( 'WDYA, permission failure' ).
ENDTRY.
li_app->if_wdy_md_object~get_definition( IMPORTING definition = es_app ).
CLEAR: es_app-author,
es_app-createdon,
es_app-changedby,
es_app-changedon.
li_map = li_app->get_properties( ).
DO li_map->size( ) TIMES.
lo_prop ?= li_map->get_by_position( sy-index ).
lo_prop->get_definition( IMPORTING definition = ls_prop ).
APPEND ls_prop TO et_properties.
ENDDO.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_app TYPE wdy_application,
lt_properties TYPE wdy_app_property_table.
read( IMPORTING es_app = ls_app
et_properties = lt_properties ).
io_xml->add( iv_name = 'APP'
ig_data = ls_app ).
io_xml->add( iv_name = 'PROPERTIES'
ig_data = lt_properties ).
ENDMETHOD.
METHOD save.
DATA: li_prop TYPE REF TO if_wdy_md_application_property,
lo_app TYPE REF TO cl_wdy_md_application.
FIELD-SYMBOLS: <ls_property> LIKE LINE OF it_properties.
TRY.
CREATE OBJECT lo_app
EXPORTING
name = is_app-application_name
definition = is_app
devclass = iv_package.
LOOP AT it_properties ASSIGNING <ls_property>.
li_prop = lo_app->if_wdy_md_application~create_property( <ls_property>-name ).
li_prop->set_value( <ls_property>-value ).
ENDLOOP.
tadir_insert( iv_package ).
lo_app->if_wdy_md_lockable_object~save_to_database( ).
CATCH cx_wdy_md_exception.
zcx_abapgit_exception=>raise( 'error saving WDYA' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_app TYPE wdy_application,
lt_properties TYPE wdy_app_property_table.
io_xml->read( EXPORTING iv_name = 'APP'
CHANGING cg_data = ls_app ).
io_xml->read( EXPORTING iv_name = 'PROPERTIES'
CHANGING cg_data = lt_properties ).
save( is_app = ls_app
it_properties = lt_properties
iv_package = iv_package ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: li_app TYPE REF TO if_wdy_md_application,
lv_objkey TYPE wdy_wb_appl_name,
lv_type TYPE seu_type,
lv_name TYPE wdy_application_name.
lv_name = ms_item-obj_name.
TRY.
li_app = cl_wdy_md_application=>get_object_by_key(
name = lv_name
version = 'A' ).
li_app->if_wdy_md_object~delete( ).
li_app->if_wdy_md_lockable_object~save_to_database( ).
lv_objkey = ms_item-obj_name.
CONCATENATE 'O' swbm_c_type_wdy_application INTO lv_type.
CALL FUNCTION 'RS_TREE_OBJECT_PLACEMENT'
EXPORTING
object = lv_objkey
type = lv_type
operation = 'DELETE'.
CATCH cx_wdy_md_not_existing.
RETURN.
CATCH cx_wdy_md_exception.
zcx_abapgit_exception=>raise( 'WDYA, error deleting' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_wapa IMPLEMENTATION.
METHOD get_page_content.
DATA: lt_content TYPE o2pageline_table,
lv_string TYPE string.
io_page->get_page(
IMPORTING
p_content = lt_content
EXCEPTIONS
invalid_call = 1
page_deleted = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |WAPA - error from get_page_content| ).
ENDIF.
CONCATENATE LINES OF lt_content INTO lv_string SEPARATED BY zif_abapgit_definitions=>c_newline RESPECTING BLANKS.
rv_content = zcl_abapgit_convert=>string_to_xstring_utf8( lv_string ).
ENDMETHOD.
METHOD read_page.
DATA: lv_name TYPE o2applname,
ls_pagekey TYPE o2pagkey,
lv_content TYPE xstring,
lv_extra TYPE string,
lv_ext TYPE string,
lo_page TYPE REF TO cl_o2_api_pages.
lv_name = ms_item-obj_name.
ls_pagekey-applname = lv_name.
ls_pagekey-pagekey = is_page-pagekey.
cl_o2_api_pages=>load(
EXPORTING
p_pagekey = ls_pagekey
IMPORTING
p_page = lo_page ).
lo_page->get_attrs(
IMPORTING
p_attrs = rs_page-attributes ).
IF rs_page-attributes-pagetype <> so2_controller.
lo_page->get_event_handlers(
IMPORTING
p_ev_handler = rs_page-event_handlers
EXCEPTIONS
page_deleted = 1
invalid_call = 2 ).
ASSERT sy-subrc = 0.
lo_page->get_parameters(
IMPORTING
p_parameters = rs_page-parameters
EXCEPTIONS
page_deleted = 1
invalid_call = 2
OTHERS = 3 ).
ASSERT sy-subrc = 0.
lo_page->get_type_source(
IMPORTING
p_source = rs_page-types
EXCEPTIONS
page_deleted = 1
invalid_call = 2
OTHERS = 3 ).
ASSERT sy-subrc = 0.
lv_content = get_page_content( lo_page ).
SPLIT is_page-pagename AT '.' INTO lv_extra lv_ext.
REPLACE ALL OCCURRENCES OF '/' IN lv_ext WITH '_-'.
REPLACE ALL OCCURRENCES OF '/' IN lv_extra WITH '_-'.
mo_files->add_raw(
iv_extra = lv_extra
iv_ext = lv_ext
iv_data = lv_content ).
CLEAR: rs_page-attributes-implclass.
ENDIF.
CLEAR: rs_page-attributes-author,
rs_page-attributes-createdon,
rs_page-attributes-changedby,
rs_page-attributes-changedon,
rs_page-attributes-changetime,
rs_page-attributes-gendate,
rs_page-attributes-gentime,
rs_page-attributes-devclass.
ENDMETHOD.
METHOD to_page_content.
DATA: lv_string TYPE string.
lv_string = zcl_abapgit_convert=>xstring_to_string_utf8( iv_content ).
SPLIT lv_string AT zif_abapgit_definitions=>c_newline INTO TABLE rt_content.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lv_name TYPE o2applname,
lt_pages TYPE STANDARD TABLE OF o2pagdir WITH DEFAULT KEY,
ls_latest LIKE LINE OF lt_pages.
lv_name = ms_item-obj_name.
SELECT * FROM o2pagdir INTO TABLE lt_pages WHERE applname = lv_name.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
RETURN.
ENDIF.
SORT lt_pages BY changedon DESCENDING changetime DESCENDING.
READ TABLE lt_pages INDEX 1 INTO ls_latest.
ASSERT sy-subrc = 0.
rv_user = ls_latest-changedby.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_name TYPE o2applname,
lo_bsp TYPE REF TO cl_o2_api_application,
ls_pagekey TYPE o2pagkey,
lv_object TYPE seu_objkey,
lt_pages TYPE o2pagelist,
lt_local_mimes TYPE o2pagename_table.
FIELD-SYMBOLS: <ls_page> LIKE LINE OF lt_pages,
<ls_local_mime> TYPE o2pagename.
lv_name = ms_item-obj_name.
cl_o2_api_application=>load(
EXPORTING
p_application_name = lv_name
IMPORTING
p_application = lo_bsp
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3 ).
ASSERT sy-subrc = 0.
lo_bsp->set_changeable(
p_changeable = abap_true
p_complete_application = abap_true ).
cl_o2_api_pages=>get_all_pages(
EXPORTING
p_applname = lv_name
p_version = c_active
IMPORTING
p_pages = lt_pages ).
LOOP AT lt_pages ASSIGNING <ls_page>.
CLEAR ls_pagekey.
ls_pagekey-applname = lv_name.
ls_pagekey-pagekey = <ls_page>-pagekey.
cl_o2_page=>delete_page_for_application(
EXPORTING
p_pagekey = ls_pagekey
EXCEPTIONS
object_not_existing = 1
error_occured = 2 ).
ASSERT sy-subrc = 0.
ENDLOOP.
lo_bsp->get_local_mimes(
IMPORTING
p_local_mimes = lt_local_mimes
EXCEPTIONS
object_invalid = 1
object_deleted = 2
error_occured = 3
OTHERS = 4 ).
LOOP AT lt_local_mimes ASSIGNING <ls_local_mime>.
CLEAR ls_pagekey.
ls_pagekey-applname = <ls_local_mime>-applname.
ls_pagekey-pagekey = <ls_local_mime>-pagekey.
cl_o2_page=>delete_page_for_application(
EXPORTING
p_pagekey = ls_pagekey
EXCEPTIONS
object_not_existing = 1
error_occured = 2 ).
ASSERT sy-subrc = 0.
ENDLOOP.
lo_bsp->delete(
EXCEPTIONS
object_not_empty = 1
object_not_changeable = 2
object_invalid = 3
action_cancelled = 4
permission_failure = 5
error_occured = 6
OTHERS = 7 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |WAPA - error from delete: { sy-subrc }| ).
ENDIF.
lv_object = lv_name.
cl_o2_api_application=>call_access_permission(
p_mode = 'FREE'
p_object = lv_object
p_complete_application = abap_true ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lo_bsp TYPE REF TO cl_o2_api_application,
ls_attributes TYPE o2applattr,
lt_nodes TYPE o2applnode_table,
lt_navgraph TYPE o2applgrap_table,
lv_obj_name TYPE string,
lv_extra TYPE string,
lv_ext TYPE string,
lo_page TYPE REF TO cl_o2_api_pages,
lt_pages_info TYPE ty_pages_tt,
ls_pagekey TYPE o2pagkey,
ls_local_page TYPE zcl_abapgit_object_wapa=>ty_page,
lt_remote_content TYPE o2pageline_table,
lt_local_content TYPE o2pageline_table,
lt_local_pages TYPE o2pagelist.
FIELD-SYMBOLS: <ls_remote_page> LIKE LINE OF lt_pages_info.
io_xml->read( EXPORTING iv_name = 'ATTRIBUTES'
CHANGING cg_data = ls_attributes ).
io_xml->read( EXPORTING iv_name = 'NAVGRAPH'
CHANGING cg_data = lt_navgraph ).
io_xml->read( EXPORTING iv_name = 'PAGES'
CHANGING cg_data = lt_pages_info ).
ls_attributes-devclass = iv_package.
cl_o2_api_application=>load(
EXPORTING
p_application_name = ls_attributes-applname " Application Name
IMPORTING
p_application = lo_bsp " Instance Created
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
CASE sy-subrc.
WHEN 0.
cl_o2_api_pages=>get_all_pages(
EXPORTING
p_applname = ls_attributes-applname
p_version = c_active
IMPORTING
p_pages = lt_local_pages ).
WHEN 1.
lo_bsp = create_new_application( is_attributes = ls_attributes
it_nodes = lt_nodes
it_navgraph = lt_navgraph ).
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Error { sy-subrc } from CL_O2_API_APPLICATION=>LOAD| ).
ENDCASE.
LOOP AT lt_pages_info ASSIGNING <ls_remote_page>.
ls_pagekey-applname = <ls_remote_page>-attributes-applname.
ls_pagekey-pagekey = <ls_remote_page>-attributes-pagekey.
cl_o2_api_pages=>load(
EXPORTING
p_pagekey = ls_pagekey
IMPORTING
p_page = lo_page
EXCEPTIONS
object_not_existing = 1
version_not_existing = 2
OTHERS = 3 ).
CASE sy-subrc.
WHEN 0.
ls_local_page = read_page( <ls_remote_page>-attributes ).
WHEN 1.
lo_page = create_new_page( <ls_remote_page>-attributes ).
WHEN 2.
" Do nothing...
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Error { sy-subrc } from CL_O2_API_PAGES=>LOAD| ).
ENDCASE.
SPLIT <ls_remote_page>-attributes-pagename AT '.' INTO lv_extra lv_ext.
REPLACE ALL OCCURRENCES OF '/' IN lv_extra WITH '_-'.
REPLACE ALL OCCURRENCES OF '/' IN lv_ext WITH '_-'.
lt_remote_content = to_page_content( mo_files->read_raw( iv_extra = lv_extra
iv_ext = lv_ext ) ).
lt_local_content = to_page_content( get_page_content( lo_page ) ).
IF ls_local_page = <ls_remote_page>
AND lt_local_content = lt_remote_content.
" no changes -> nothing to do
CONTINUE.
ENDIF.
IF <ls_remote_page>-attributes-pagetype <> so2_controller.
lo_page->set_page( lt_remote_content ).
lo_page->set_event_handlers( <ls_remote_page>-event_handlers ).
lo_page->set_parameters( <ls_remote_page>-parameters ).
lo_page->set_type_source( <ls_remote_page>-types ).
ENDIF.
lo_page->save( p_with_all_texts = abap_true ).
lv_obj_name = cl_wb_object_type=>get_concatenated_key_from_id(
p_key_component1 = <ls_remote_page>-attributes-applname
p_key_component2 = <ls_remote_page>-attributes-pagekey
p_external_id = 'WG ' ).
zcl_abapgit_objects_activation=>add( iv_type = 'WAPP'
iv_name = lv_obj_name ).
ENDLOOP.
delete_superfluous_pages( it_local_pages = lt_local_pages
it_remote_pages = lt_pages_info ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_name TYPE o2applname.
lv_name = ms_item-obj_name.
cl_o2_api_application=>load(
EXPORTING
p_application_name = lv_name
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3 ).
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_name TYPE o2applname,
ls_attributes TYPE o2applattr,
lt_navgraph TYPE o2applgrap_table,
lt_pages TYPE o2pagelist,
lt_pages_info TYPE ty_pages_tt,
lo_bsp TYPE REF TO cl_o2_api_application.
FIELD-SYMBOLS: <ls_page> LIKE LINE OF lt_pages.
lv_name = ms_item-obj_name.
cl_o2_api_application=>load(
EXPORTING
p_application_name = lv_name
IMPORTING
p_application = lo_bsp
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3 ).
IF sy-subrc <> 0.
RETURN.
ENDIF.
lo_bsp->get_attributes(
EXPORTING
p_version = c_active
IMPORTING
p_attributes = ls_attributes ).
CLEAR: ls_attributes-author,
ls_attributes-createdon,
ls_attributes-changedby,
ls_attributes-changedon,
ls_attributes-devclass.
io_xml->add( iv_name = 'ATTRIBUTES'
ig_data = ls_attributes ).
lo_bsp->get_navgraph(
EXPORTING
p_version = c_active
IMPORTING
p_navgraph = lt_navgraph ).
io_xml->add( iv_name = 'NAVGRAPH'
ig_data = lt_navgraph ).
cl_o2_api_pages=>get_all_pages(
EXPORTING
p_applname = lv_name
p_version = c_active
IMPORTING
p_pages = lt_pages ).
LOOP AT lt_pages ASSIGNING <ls_page>.
APPEND read_page( <ls_page> ) TO lt_pages_info.
ENDLOOP.
io_xml->add( iv_name = 'PAGES'
ig_data = lt_pages_info ).
ENDMETHOD.
METHOD create_new_application.
DATA: ls_item LIKE ms_item,
lv_objkey TYPE seu_objkey.
cl_o2_api_application=>create_new(
EXPORTING
p_application_data = is_attributes
p_nodes = it_nodes
p_navgraph = it_navgraph
IMPORTING
p_application = ro_bsp
EXCEPTIONS
object_already_existing = 1
object_just_created = 2
not_authorized = 3
undefined_name = 4
author_not_existing = 5
action_cancelled = 6
error_occured = 7
invalid_parameter = 8 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |WAPA - error from create_new: { sy-subrc }| ).
ENDIF.
ro_bsp->save( ).
ro_bsp->set_changeable(
p_changeable = abap_false
p_complete_application = abap_true ).
ls_item-obj_type = 'WAPD'.
ls_item-obj_name = ms_item-obj_name.
zcl_abapgit_objects_activation=>add_item( ls_item ).
lv_objkey = ls_item-obj_name.
cl_o2_api_application=>activate( lv_objkey ).
ENDMETHOD.
METHOD create_new_page.
cl_o2_api_pages=>create_new_page(
EXPORTING
p_pageattrs = is_page_attributes
IMPORTING
p_page = ro_page
EXCEPTIONS
object_already_exists = 1
invalid_name = 2
error_occured = 3
o2appl_not_existing = 4
OTHERS = 5 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error { sy-subrc } from CL_O2_API_PAGES=>CREATE_NEW_PAGE| ).
ENDIF.
ENDMETHOD.
METHOD delete_superfluous_pages.
DATA: ls_pagekey TYPE o2pagkey.
FIELD-SYMBOLS: <ls_local_page> LIKE LINE OF it_local_pages.
" delete local pages which doesn't exists remotely
LOOP AT it_local_pages ASSIGNING <ls_local_page>.
READ TABLE it_remote_pages WITH KEY attributes-pagekey = <ls_local_page>-pagekey
TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
" page exists locally but not remotely -> delete
ls_pagekey-applname = <ls_local_page>-applname.
ls_pagekey-pagekey = <ls_local_page>-pagekey.
cl_o2_page=>delete_page_for_application(
EXPORTING
p_pagekey = ls_pagekey
EXCEPTIONS
object_not_existing = 1
error_occured = 2 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error { sy-subrc } from CL_O2_PAGE=>DELETE_PAGE_FOR_APPLICATION| ).
ENDIF.
ENDIF.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_w3super IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item iv_language = iv_language ).
ms_key-relid = ms_item-obj_type+2(2).
ms_key-objid = ms_item-obj_name.
ENDMETHOD.
METHOD find_param.
FIELD-SYMBOLS <ls_param> LIKE LINE OF it_params.
READ TABLE it_params ASSIGNING <ls_param> WITH KEY name = iv_name.
IF sy-subrc > 0.
zcx_abapgit_exception=>raise( |W3xx: Cannot find { iv_name } for { ms_key-objid }| ).
ENDIF.
rv_value = <ls_param>-value.
ENDMETHOD.
METHOD get_ext.
rv_ext = find_param( it_params = it_params iv_name = c_param_names-fileext ).
SHIFT rv_ext LEFT DELETING LEADING '.'.
ENDMETHOD.
METHOD get_metadata. "Redefinition
rs_metadata = super->get_metadata( ).
rs_metadata-version = 'v2.0.0'. " Seriazation v2, separate data file
ENDMETHOD.
METHOD normalize_params.
FIELD-SYMBOLS <ls_param> LIKE LINE OF ct_params.
" Ensure filesize param exists
READ TABLE ct_params ASSIGNING <ls_param> WITH KEY name = c_param_names-filesize.
IF sy-subrc <> 0.
APPEND INITIAL LINE TO ct_params ASSIGNING <ls_param>.
<ls_param>-name = c_param_names-filesize.
ENDIF.
LOOP AT ct_params ASSIGNING <ls_param>.
<ls_param>-relid = ms_key-relid. " Ensure param key = object key
<ls_param>-objid = ms_key-objid.
IF <ls_param>-name = c_param_names-filesize. " Patch filesize = real file size
<ls_param>-value = iv_size.
CONDENSE <ls_param>-value.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD strip_params.
FIELD-SYMBOLS <ls_param> LIKE LINE OF ct_params.
" Remove path from filename
find_param( it_params = ct_params iv_name = c_param_names-filename ). " Check exists
READ TABLE ct_params ASSIGNING <ls_param> WITH KEY name = c_param_names-filename.
<ls_param>-value = zcl_abapgit_path=>get_filename_from_syspath( |{ <ls_param>-value }| ).
" Clear version & filesize
DELETE ct_params WHERE name = c_param_names-version.
DELETE ct_params WHERE name = c_param_names-filesize.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE chname INTO rv_user
FROM wwwdata
WHERE relid = ms_key-relid
AND objid = ms_key-objid
AND srtf2 = 0.
IF sy-subrc IS NOT INITIAL OR rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
CALL FUNCTION 'WWWDATA_DELETE'
EXPORTING
key = ms_key
EXCEPTIONS
wrong_object_type = 1
delete_error = 2.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot delete W3xx data' ).
ENDIF.
CALL FUNCTION 'WWWPARAMS_DELETE_ALL'
EXPORTING
key = ms_key
EXCEPTIONS
delete_error = 1.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot delete W3xx params' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA lv_base64str TYPE string.
DATA lt_w3params TYPE STANDARD TABLE OF wwwparams.
DATA lv_xstring TYPE xstring.
DATA lt_w3mime TYPE STANDARD TABLE OF w3mime.
DATA lt_w3html TYPE STANDARD TABLE OF w3html.
DATA lv_size TYPE int4.
DATA lv_tadir_obj TYPE tadir-object.
io_xml->read( EXPORTING iv_name = 'TEXT'
CHANGING cg_data = ms_key-text ).
io_xml->read( EXPORTING iv_name = 'PARAMS'
CHANGING cg_data = lt_w3params ).
CASE io_xml->get_metadata( )-version.
WHEN 'v1.0.0'.
io_xml->read( EXPORTING iv_name = 'DATA'
CHANGING cg_data = lv_base64str ).
lv_xstring = cl_http_utility=>decode_x_base64( lv_base64str ).
WHEN 'v2.0.0'.
lv_xstring = zif_abapgit_object~mo_files->read_raw( iv_extra = 'data'
iv_ext = get_ext( lt_w3params ) ).
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'W3xx: Unknown serializer version' ).
ENDCASE.
CASE ms_key-relid.
WHEN 'MI'.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xstring
IMPORTING
output_length = lv_size
TABLES
binary_tab = lt_w3mime.
WHEN 'HT'.
CALL FUNCTION 'SCMS_XSTRING_TO_BINARY'
EXPORTING
buffer = lv_xstring
IMPORTING
output_length = lv_size
TABLES
binary_tab = lt_w3mime.
CALL FUNCTION 'SCMS_BINARY_TO_TEXT'
EXPORTING
input_length = lv_size
IMPORTING
output_length = lv_size
TABLES
binary_tab = lt_w3mime
text_tab = lt_w3html
EXCEPTIONS
failed = 1.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot update W3xx params' ).
ENDIF.
CLEAR lt_w3mime.
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'Wrong W3xx type' ).
ENDCASE.
" Update size of file based on actual data file size, prove param object name
normalize_params( EXPORTING iv_size = lv_size
CHANGING ct_params = lt_w3params ).
CALL FUNCTION 'WWWPARAMS_UPDATE'
TABLES
params = lt_w3params
EXCEPTIONS
update_error = 1.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot update W3xx params' ).
ENDIF.
ms_key-tdate = sy-datum.
ms_key-ttime = sy-uzeit.
ms_key-chname = sy-uname.
ms_key-devclass = iv_package.
CALL FUNCTION 'WWWDATA_EXPORT'
EXPORTING
key = ms_key
TABLES
mime = lt_w3mime
html = lt_w3html
EXCEPTIONS
wrong_object_type = 1
export_error = 2.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot upload W3xx data' ).
ENDIF.
CONCATENATE 'W3' ms_key-relid INTO lv_tadir_obj.
CALL FUNCTION 'TR_TADIR_INTERFACE'
EXPORTING
wi_tadir_pgmid = 'R3TR'
wi_tadir_object = lv_tadir_obj
wi_tadir_devclass = iv_package
wi_tadir_obj_name = ms_key-objid
wi_test_modus = space
EXCEPTIONS
tadir_entry_not_existing = 1
tadir_entry_ill_type = 2
no_systemname = 3
no_systemtype = 4
original_system_conflict = 5
object_reserved_for_devclass = 6
object_exists_global = 7
object_exists_local = 8
object_is_distributed = 9
obj_specification_not_unique = 10
no_authorization_to_delete = 11
devclass_not_existing = 12
simultanious_set_remove_repair = 13
order_missing = 14
no_modification_of_head_syst = 15
pgmid_object_not_allowed = 16
masterlanguage_not_specified = 17
devclass_not_specified = 18
specify_owner_unique = 19
loc_priv_objs_no_repair = 20
gtadir_not_reached = 21
object_locked_for_order = 22
change_of_class_not_allowed = 23
no_change_from_sap_to_tmp = 24
OTHERS = 99.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot update TADIR for W3xx' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
SELECT SINGLE objid INTO ms_key-objid
FROM wwwdata
WHERE relid = ms_key-relid
AND objid = ms_key-objid
AND srtf2 = 0.
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
rv_bool = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_bdcdata TYPE bdcdata,
lt_bdcdata TYPE tty_bdcdata.
ls_bdcdata-program = 'SAPMWWW0'.
ls_bdcdata-dynpro = '0100'.
ls_bdcdata-dynbegin = 'X'.
APPEND ls_bdcdata TO lt_bdcdata.
change_bdc_jump_data(
CHANGING
ct_bdcdata = lt_bdcdata ).
CLEAR ls_bdcdata.
ls_bdcdata-fnam = 'BDC_OKCODE'.
ls_bdcdata-fval = '=CRO1'.
APPEND ls_bdcdata TO lt_bdcdata.
ls_bdcdata-program = 'RSWWWSHW'.
ls_bdcdata-dynpro = '1000'.
ls_bdcdata-dynbegin = 'X'.
APPEND ls_bdcdata TO lt_bdcdata.
CLEAR ls_bdcdata.
ls_bdcdata-fnam = 'SO_OBJID-LOW'.
ls_bdcdata-fval = ms_item-obj_name.
APPEND ls_bdcdata TO lt_bdcdata.
CLEAR ls_bdcdata.
ls_bdcdata-fnam = 'BDC_OKCODE'.
ls_bdcdata-fval = '=ONLI'.
APPEND ls_bdcdata TO lt_bdcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SMW0'
mode_val = 'E'
TABLES
using_tab = lt_bdcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SE35' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA lt_w3mime TYPE STANDARD TABLE OF w3mime.
DATA lt_w3html TYPE STANDARD TABLE OF w3html.
DATA lt_w3params TYPE STANDARD TABLE OF wwwparams.
DATA lv_xstring TYPE xstring.
DATA lv_size TYPE int4.
SELECT SINGLE * INTO CORRESPONDING FIELDS OF ms_key
FROM wwwdata
WHERE relid = ms_key-relid
AND objid = ms_key-objid
AND srtf2 = 0.
IF sy-subrc IS NOT INITIAL.
RETURN.
ENDIF.
CALL FUNCTION 'WWWDATA_IMPORT'
EXPORTING
key = ms_key
TABLES
mime = lt_w3mime
html = lt_w3html
EXCEPTIONS
wrong_object_type = 1
import_error = 2.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot read W3xx data' ).
ENDIF.
CALL FUNCTION 'WWWPARAMS_READ_ALL'
EXPORTING
type = ms_key-relid
objid = ms_key-objid
TABLES
params = lt_w3params
EXCEPTIONS
entry_not_exists = 1.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot read W3xx data' ).
ENDIF.
lv_size = find_param( it_params = lt_w3params iv_name = c_param_names-filesize ).
" Clean params (remove version, filesize & clear filename from path)
strip_params( CHANGING ct_params = lt_w3params ).
CASE ms_key-relid.
WHEN 'MI'.
CALL FUNCTION 'SCMS_BINARY_TO_XSTRING'
EXPORTING
input_length = lv_size
IMPORTING
buffer = lv_xstring
TABLES
binary_tab = lt_w3mime
EXCEPTIONS
failed = 1.
WHEN 'HT'.
CALL FUNCTION 'SCMS_TEXT_TO_XSTRING'
IMPORTING
buffer = lv_xstring
TABLES
text_tab = lt_w3html
EXCEPTIONS
failed = 1.
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'Wrong W3xx type' ).
ENDCASE.
IF sy-subrc IS NOT INITIAL.
zcx_abapgit_exception=>raise( 'Cannot convert W3xx to xstring' ).
ENDIF.
io_xml->add( iv_name = 'NAME'
ig_data = ms_key-objid ).
io_xml->add( iv_name = 'TEXT'
ig_data = ms_key-text ).
io_xml->add( iv_name = 'PARAMS'
ig_data = lt_w3params ).
" Seriazation v2, separate data file. 'extra' added to prevent conflict with .xml
zif_abapgit_object~mo_files->add_raw( iv_data = lv_xstring
iv_extra = 'data'
iv_ext = get_ext( lt_w3params ) ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE eqegraarg.
lv_object = |{ ms_item-obj_type+2(2) }{ ms_item-obj_name }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'E_WWW_HTML'
iv_argument = lv_object ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_w3mi IMPLEMENTATION.
METHOD change_bdc_jump_data.
DATA: ls_bdcdata LIKE LINE OF ct_bdcdata.
ls_bdcdata-fnam = 'RADIO_HT'.
ls_bdcdata-fval = ' '.
APPEND ls_bdcdata TO ct_bdcdata.
CLEAR ls_bdcdata.
ls_bdcdata-fnam = 'RADIO_MI'.
ls_bdcdata-fval = 'X'.
APPEND ls_bdcdata TO ct_bdcdata.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_w3ht IMPLEMENTATION.
METHOD change_bdc_jump_data.
DATA: ls_bdcdata LIKE LINE OF ct_bdcdata.
ls_bdcdata-fnam = 'RADIO_HT'.
ls_bdcdata-fval = 'X'.
APPEND ls_bdcdata TO ct_bdcdata.
CLEAR ls_bdcdata.
ls_bdcdata-fnam = 'RADIO_MI'.
ls_bdcdata-fval = ' '.
APPEND ls_bdcdata TO ct_bdcdata.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_VIEW IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE as4user FROM dd25l INTO rv_user
WHERE viewname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objname TYPE rsedd0-ddobjname.
lv_objname = ms_item-obj_name.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = abap_true
objname = lv_objname
objtype = 'V'
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, VIEW' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_name TYPE ddobjname,
ls_dd25v TYPE dd25v,
ls_dd09l TYPE dd09l,
lt_dd26v TYPE TABLE OF dd26v,
lt_dd27p TYPE TABLE OF dd27p,
lt_dd28j TYPE TABLE OF dd28j,
lt_dd28v TYPE TABLE OF dd28v.
io_xml->read( EXPORTING iv_name = 'DD25V'
CHANGING cg_data = ls_dd25v ).
io_xml->read( EXPORTING iv_name = 'DD09L'
CHANGING cg_data = ls_dd09l ).
io_xml->read( EXPORTING iv_name = 'DD26V_TABLE'
CHANGING cg_data = lt_dd26v ).
io_xml->read( EXPORTING iv_name = 'DD27P_TABLE'
CHANGING cg_data = lt_dd27p ).
io_xml->read( EXPORTING iv_name = 'DD28J_TABLE'
CHANGING cg_data = lt_dd28j ).
io_xml->read( EXPORTING iv_name = 'DD28V_TABLE'
CHANGING cg_data = lt_dd28v ).
corr_insert( iv_package ).
lv_name = ms_item-obj_name. " type conversion
CALL FUNCTION 'DDIF_VIEW_PUT'
EXPORTING
name = lv_name
dd25v_wa = ls_dd25v
dd09l_wa = ls_dd09l
TABLES
dd26v_tab = lt_dd26v
dd27p_tab = lt_dd27p
dd28j_tab = lt_dd28j
dd28v_tab = lt_dd28v
EXCEPTIONS
view_not_found = 1
name_inconsistent = 2
view_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_VIEW_PUT' ).
ENDIF.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_viewname TYPE dd25l-viewname,
lv_ddl_view TYPE abap_bool.
SELECT SINGLE viewname FROM dd25l INTO lv_viewname
WHERE viewname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_bool = boolc( sy-subrc = 0 ).
IF rv_bool = abap_true.
TRY.
CALL METHOD ('CL_DD_DDL_UTILITIES')=>('CHECK_FOR_DDL_VIEW')
EXPORTING
objname = lv_viewname
RECEIVING
is_ddl_view = lv_ddl_view.
IF lv_ddl_view = abap_true.
rv_bool = abap_false.
ENDIF.
CATCH cx_root ##NO_HANDLER.
ENDTRY.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA: lv_date TYPE dats,
lv_time TYPE tims.
SELECT SINGLE as4date as4time FROM dd25l
INTO (lv_date, lv_time)
WHERE viewname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
SELECT SINGLE as4date as4time FROM dd09l
INTO (lv_date, lv_time)
WHERE tabname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
jump_se11( iv_radio = 'RSRD1-VIMA'
iv_field = 'RSRD1-VIMA_VAL' ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_name TYPE ddobjname,
ls_dd25v TYPE dd25v,
ls_dd09l TYPE dd09l,
lt_dd26v TYPE TABLE OF dd26v,
lt_dd27p TYPE TABLE OF dd27p,
lt_dd28j TYPE TABLE OF dd28j,
lt_dd28v TYPE TABLE OF dd28v.
FIELD-SYMBOLS: <ls_dd27p> LIKE LINE OF lt_dd27p.
lv_name = ms_item-obj_name.
CALL FUNCTION 'DDIF_VIEW_GET'
EXPORTING
name = lv_name
state = 'A'
langu = mv_language
IMPORTING
dd25v_wa = ls_dd25v
dd09l_wa = ls_dd09l
TABLES
dd26v_tab = lt_dd26v
dd27p_tab = lt_dd27p
dd28j_tab = lt_dd28j
dd28v_tab = lt_dd28v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_VIEW_GET' ).
ENDIF.
IF ls_dd25v IS INITIAL.
RETURN. " does not exist in system
ENDIF.
CLEAR: ls_dd25v-as4user,
ls_dd25v-as4date,
ls_dd25v-as4time.
CLEAR: ls_dd09l-as4user,
ls_dd09l-as4date,
ls_dd09l-as4time.
LOOP AT lt_dd27p ASSIGNING <ls_dd27p>.
CLEAR: <ls_dd27p>-ddtext,
<ls_dd27p>-reptext,
<ls_dd27p>-scrtext_s,
<ls_dd27p>-scrtext_m,
<ls_dd27p>-scrtext_l,
<ls_dd27p>-outputlen,
<ls_dd27p>-decimals,
<ls_dd27p>-lowercase,
<ls_dd27p>-convexit,
<ls_dd27p>-signflag,
<ls_dd27p>-flength,
<ls_dd27p>-domname,
<ls_dd27p>-datatype,
<ls_dd27p>-entitytab,
<ls_dd27p>-inttype,
<ls_dd27p>-intlen,
<ls_dd27p>-headlen,
<ls_dd27p>-scrlen1,
<ls_dd27p>-scrlen2,
<ls_dd27p>-scrlen3,
<ls_dd27p>-memoryid.
ENDLOOP.
io_xml->add( iv_name = 'DD25V'
ig_data = ls_dd25v ).
io_xml->add( iv_name = 'DD09L'
ig_data = ls_dd09l ).
io_xml->add( ig_data = lt_dd26v
iv_name = 'DD26V_TABLE' ).
io_xml->add( ig_data = lt_dd27p
iv_name = 'DD27P_TABLE' ).
io_xml->add( ig_data = lt_dd28j
iv_name = 'DD28J_TABLE' ).
io_xml->add( ig_data = lt_dd28v
iv_name = 'DD28V_TABLE' ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_VCLS IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_vclname TYPE vcl_name.
lv_vclname = ms_item-obj_name.
DELETE FROM vcldir WHERE vclname = lv_vclname. "#EC CI_SUBRC
DELETE FROM vcldirt WHERE vclname = lv_vclname. "#EC CI_NOFIRST "#EC CI_SUBRC
DELETE FROM vclstruc WHERE vclname = lv_vclname. "#EC CI_SUBRC
DELETE FROM vclstruct WHERE vclname = lv_vclname. "#EC CI_NOFIRST "#EC CI_SUBRC
DELETE FROM vclstrudep WHERE vclname = lv_vclname. "#EC CI_SUBRC
DELETE FROM vclmf WHERE vclname = lv_vclname. "#EC CI_SUBRC
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_vcldir_entry TYPE v_vcldir,
lt_vclstruc TYPE TABLE OF v_vclstruc,
lt_vclstrudep TYPE TABLE OF v_vclstdep,
lt_vclmf TYPE TABLE OF v_vclmf,
lv_objectname TYPE ob_object.
io_xml->read( EXPORTING iv_name = 'VCLDIR'
CHANGING cg_data = ls_vcldir_entry ).
io_xml->read( EXPORTING iv_name = 'VLCSTRUC_TAB'
CHANGING cg_data = lt_vclstruc ).
io_xml->read( EXPORTING iv_name = 'VCLSTRUDEP_TAB'
CHANGING cg_data = lt_vclstrudep ).
io_xml->read( EXPORTING iv_name = 'lt_vclstrudep'
CHANGING cg_data = lt_vclmf ).
ls_vcldir_entry-author = sy-uname.
CALL FUNCTION 'VIEWCLUSTER_SAVE_DEFINITION'
EXPORTING
vcldir_entry = ls_vcldir_entry
TABLES
vclstruc_tab = lt_vclstruc
vclstrudep_tab = lt_vclstrudep
vclmf_tab = lt_vclmf.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = ms_item-obj_name
object_class = ms_item-obj_type
devclass = iv_package
master_language = mv_language
mode = 'INSERT'
global_lock = abap_true
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc = 1.
zcx_abapgit_exception=>raise( 'Cancelled' ).
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT' ).
ENDIF.
lv_objectname = ls_vcldir_entry-vclname.
CALL FUNCTION 'OBJ_GENERATE'
EXPORTING
iv_objectname = lv_objectname
iv_objecttype = c_cluster_type
iv_maint_mode = c_mode_insert
iv_devclass = iv_package
EXCEPTIONS
illegal_call = 1
object_not_found = 2
generate_error = 3
transport_error = 4
object_enqueue_failed = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error in OBJ_GENERATE for VCLS' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA lv_changedate TYPE vcldir-changedate.
SELECT SINGLE changedate INTO lv_changedate FROM vcldir
WHERE vclname = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
IF lv_changedate IS INITIAL.
rv_bool = abap_false.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
ls_bcdata-program = 'SAPMSVIM'.
ls_bcdata-dynpro = '0050'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'VIMDYNFLDS-VIEWNAME'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'VIMDYNFLDS-STRUCT_MNT'.
ls_bcdata-fval = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=CLUS'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-program = 'SAPMSVIM'.
ls_bcdata-dynpro = '0052 '.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'VIMDYNFLDS-VCLNAME'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=CLSH'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SE54'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SE35' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_vclname TYPE vcl_name,
ls_vcldir_entry TYPE v_vcldir,
lt_vclstruc TYPE TABLE OF v_vclstruc,
lt_vclstrudep TYPE TABLE OF v_vclstdep,
lt_vclmf TYPE TABLE OF v_vclmf.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
lv_vclname = ms_item-obj_name.
CALL FUNCTION 'VIEWCLUSTER_GET_DEFINITION'
EXPORTING
vclname = lv_vclname
IMPORTING
vcldir_entry = ls_vcldir_entry
TABLES
vclstruc_tab = lt_vclstruc
vclstrudep_tab = lt_vclstrudep
vclmf_tab = lt_vclmf
EXCEPTIONS
viewcluster_not_found = 1
incomplete_viewcluster = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error in VIEWCLUSTER_GET_DEFINITION' ).
ENDIF.
CLEAR ls_vcldir_entry-author.
io_xml->add( iv_name = 'VCLDIR'
ig_data = ls_vcldir_entry ).
io_xml->add( iv_name = 'VLCSTRUC_TAB'
ig_data = lt_vclstruc ).
io_xml->add( iv_name = 'VCLSTRUDEP_TAB'
ig_data = lt_vclstrudep ).
io_xml->add( iv_name = 'VCLMF_TAB'
ig_data = lt_vclmf ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_UCSA IMPLEMENTATION.
METHOD clear_dynamic_fields.
FIELD-SYMBOLS: <lg_header> TYPE any.
ASSIGN COMPONENT 'HEADER' OF STRUCTURE cg_complete_comm_assembly
TO <lg_header>.
ASSERT sy-subrc = 0.
clear_field(
EXPORTING iv_fieldname = 'CREATEDBY'
CHANGING cg_header = <lg_header> ).
clear_field(
EXPORTING iv_fieldname = 'CREATEDON'
CHANGING cg_header = <lg_header> ).
clear_field(
EXPORTING iv_fieldname = 'CREATEDAT'
CHANGING cg_header = <lg_header> ).
clear_field(
EXPORTING iv_fieldname = 'CHANGEDBY'
CHANGING cg_header = <lg_header> ).
clear_field(
EXPORTING iv_fieldname = 'CHANGEDON'
CHANGING cg_header = <lg_header> ).
clear_field(
EXPORTING iv_fieldname = 'CHANGEDAT'
CHANGING cg_header = <lg_header> ).
ENDMETHOD.
METHOD clear_field.
FIELD-SYMBOLS: <lg_field> TYPE any.
ASSIGN COMPONENT iv_fieldname OF STRUCTURE cg_header
TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ENDMETHOD.
METHOD get_persistence.
CALL METHOD ('CL_UCON_SA_DB_PERSIST')=>('IF_UCON_SA_PERSIST~GET_INSTANCE')
EXPORTING
id = iv_id
RECEIVING
instance = ro_persistence.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_id TYPE ty_id,
lx_root TYPE REF TO cx_root,
lv_text TYPE string,
lo_persistence TYPE REF TO object.
TRY.
lv_id = ms_item-obj_name.
lo_persistence = get_persistence( lv_id ).
CALL METHOD lo_persistence->('IF_UCON_SA_PERSIST~DELETE')
EXPORTING
version = zif_abapgit_definitions=>c_version-active.
CATCH cx_root INTO lx_root.
lv_text = lx_root->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_id TYPE ty_id,
lx_root TYPE REF TO cx_root,
lv_text TYPE string,
lo_persistence TYPE REF TO object,
lr_complete_comm_assembly TYPE REF TO data.
FIELD-SYMBOLS: <lg_complete_comm_assembly> TYPE any.
TRY.
CREATE DATA lr_complete_comm_assembly TYPE ('UCONSERVASCOMPLETE').
ASSIGN lr_complete_comm_assembly->* TO <lg_complete_comm_assembly>.
ASSERT sy-subrc = 0.
io_xml->read(
EXPORTING
iv_name = 'UCSA'
CHANGING
cg_data = <lg_complete_comm_assembly> ).
lv_id = ms_item-obj_name.
lo_persistence = get_persistence( lv_id ).
CALL METHOD lo_persistence->('IF_UCON_SA_PERSIST~CREATE').
CALL METHOD lo_persistence->('IF_UCON_SA_PERSIST~SAVE')
EXPORTING
sa = <lg_complete_comm_assembly>
version = zif_abapgit_definitions=>c_version-active.
tadir_insert( iv_package ).
CATCH cx_root INTO lx_root.
lv_text = lx_root->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_id TYPE ty_id,
lo_persistence TYPE REF TO object.
lv_id = ms_item-obj_name.
TRY.
lo_persistence = get_persistence( lv_id ).
" Interface IF_UCON_SA_PERSIST and other objects are not present
" in lower Netweaver realeses. Therefore we have to call them
" dynamically to be downward comapatible.
CALL METHOD lo_persistence->('IF_UCON_SA_PERSIST~LOAD')
EXPORTING
version = zif_abapgit_definitions=>c_version-active
language = sy-langu.
CATCH cx_root.
rv_bool = abap_false.
RETURN.
ENDTRY.
rv_bool = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
in_new_window = abap_true
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_TOOL_ACCESS' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_id TYPE ty_id,
lx_root TYPE REF TO cx_root,
lv_text TYPE string,
lo_persistence TYPE REF TO object,
lr_complete_comm_assembly TYPE REF TO data.
FIELD-SYMBOLS: <lg_complete_comm_assembly> TYPE any.
lv_id = ms_item-obj_name.
TRY.
CREATE DATA lr_complete_comm_assembly TYPE ('UCONSERVASCOMPLETE').
ASSIGN lr_complete_comm_assembly->* TO <lg_complete_comm_assembly>.
ASSERT sy-subrc = 0.
lo_persistence = get_persistence( lv_id ).
CALL METHOD lo_persistence->('IF_UCON_SA_PERSIST~LOAD')
EXPORTING
version = zif_abapgit_definitions=>c_version-active
language = sy-langu
IMPORTING
sa = <lg_complete_comm_assembly>.
clear_dynamic_fields( CHANGING cg_complete_comm_assembly = <lg_complete_comm_assembly> ).
io_xml->add( iv_name = 'UCSA'
ig_data = <lg_complete_comm_assembly> ).
CATCH cx_root INTO lx_root.
lv_text = lx_root->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_type IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
TRY.
read( ).
rv_bool = abap_true.
CATCH zcx_abapgit_not_found zcx_abapgit_exception.
rv_bool = abap_false.
ENDTRY.
ENDMETHOD.
METHOD read.
DATA: lv_typdname TYPE rsedd0-typegroup,
lt_psmodisrc TYPE TABLE OF smodisrc,
lt_psmodilog TYPE TABLE OF smodilog,
lt_ptrdir TYPE TABLE OF trdir.
SELECT SINGLE ddtext FROM ddtypet
INTO ev_ddtext
WHERE typegroup = ms_item-obj_name
AND ddlanguage = mv_language.
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE zcx_abapgit_not_found.
ENDIF.
lv_typdname = ms_item-obj_name.
CALL FUNCTION 'TYPD_GET_OBJECT'
EXPORTING
typdname = lv_typdname
TABLES
psmodisrc = lt_psmodisrc
psmodilog = lt_psmodilog
psource = et_source
ptrdir = lt_ptrdir
EXCEPTIONS
version_not_found = 1
reps_not_exist = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from TYPD_GET_OBJECT' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_ddtext TYPE ddtypet-ddtext,
lt_source TYPE abaptxt255_tab.
TRY.
read( IMPORTING
ev_ddtext = lv_ddtext
et_source = lt_source ).
CATCH zcx_abapgit_not_found.
RETURN.
ENDTRY.
io_xml->add( iv_name = 'DDTEXT'
ig_data = lv_ddtext ).
mo_files->add_abap( lt_source ).
ENDMETHOD.
METHOD create.
DATA: lv_progname TYPE reposrc-progname,
lv_typegroup TYPE rsedd0-typegroup.
lv_typegroup = ms_item-obj_name.
CALL FUNCTION 'RS_DD_TYGR_INSERT_SOURCES'
EXPORTING
typegroupname = lv_typegroup
ddtext = iv_ddtext
corrnum = ''
devclass = iv_devclass
TABLES
source = it_source
EXCEPTIONS
already_exists = 1
not_executed = 2
permission_failure = 3
object_not_specified = 4
illegal_name = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_TYGR_INSERT_SOURCES' ).
ENDIF.
CONCATENATE c_prefix lv_typegroup INTO lv_progname.
UPDATE progdir SET uccheck = abap_true
WHERE name = lv_progname.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error setting uccheck' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_ddtext TYPE ddtypet-ddtext,
lt_source TYPE abaptxt255_tab,
lv_progname TYPE reposrc-progname,
lv_typegroup TYPE rsedd0-typegroup.
lv_typegroup = ms_item-obj_name.
io_xml->read( EXPORTING iv_name = 'DDTEXT'
CHANGING cg_data = lv_ddtext ).
lt_source = mo_files->read_abap( ).
IF zif_abapgit_object~exists( ) = abap_false.
create( iv_ddtext = lv_ddtext
it_source = lt_source
iv_devclass = iv_package ).
ELSE.
CONCATENATE c_prefix lv_typegroup INTO lv_progname.
INSERT REPORT lv_progname FROM lt_source STATE 'I'.
ENDIF.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objname TYPE rsedd0-ddobjname.
lv_objname = ms_item-obj_name.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = abap_true
objname = lv_objname
objtype = 'G'
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4
dialog_needed = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error deleting TYPE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
jump_se11( iv_radio = 'RSRD1-TYMA'
iv_field = 'RSRD1-TYMA_VAL' ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ttyp IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
DATA: lv_date TYPE dats,
lv_time TYPE tims.
SELECT SINGLE as4date as4time FROM dd40l
INTO (lv_date, lv_time)
WHERE typename = ms_item-obj_name
AND as4local = 'A'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE as4user FROM dd40l INTO rv_user
WHERE typename = ms_item-obj_name
AND as4local = 'A'.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_typename TYPE dd40l-typename.
SELECT SINGLE typename FROM dd40l INTO lv_typename
WHERE typename = ms_item-obj_name
AND as4local = 'A'.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
jump_se11( iv_radio = 'RSRD1-DDTYPE'
iv_field = 'RSRD1-DDTYPE_VAL' ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objname TYPE rsedd0-ddobjname.
lv_objname = ms_item-obj_name.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = abap_true
objname = lv_objname
objtype = 'A'
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, TTYP' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_name TYPE ddobjname,
lt_dd42v TYPE dd42v_tab,
lt_dd43v TYPE dd43v_tab,
ls_dd40v TYPE dd40v.
lv_name = ms_item-obj_name.
CALL FUNCTION 'DDIF_TTYP_GET'
EXPORTING
name = lv_name
state = 'A'
langu = mv_language
IMPORTING
dd40v_wa = ls_dd40v
TABLES
dd42v_tab = lt_dd42v
dd43v_tab = lt_dd43v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_TTYP_GET' ).
ENDIF.
IF ls_dd40v IS INITIAL.
RETURN. " does not exist in system
ENDIF.
CLEAR: ls_dd40v-as4user,
ls_dd40v-as4date,
ls_dd40v-as4time.
IF NOT ls_dd40v-rowkind IS INITIAL.
CLEAR ls_dd40v-typelen.
ENDIF.
io_xml->add( iv_name = 'DD40V'
ig_data = ls_dd40v ).
io_xml->add( iv_name = 'DD42V'
ig_data = lt_dd42v ).
io_xml->add( iv_name = 'DD43V'
ig_data = lt_dd43v ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_name TYPE ddobjname,
lt_dd42v TYPE dd42v_tab,
lt_dd43v TYPE dd43v_tab,
ls_dd40v TYPE dd40v.
io_xml->read( EXPORTING iv_name = 'DD40V'
CHANGING cg_data = ls_dd40v ).
io_xml->read( EXPORTING iv_name = 'DD42V'
CHANGING cg_data = lt_dd42v ).
io_xml->read( EXPORTING iv_name = 'DD43V'
CHANGING cg_data = lt_dd43v ).
corr_insert( iv_package ).
lv_name = ms_item-obj_name. " type conversion
CALL FUNCTION 'DDIF_TTYP_PUT'
EXPORTING
name = lv_name
dd40v_wa = ls_dd40v
TABLES
dd42v_tab = lt_dd42v
dd43v_tab = lt_dd43v
EXCEPTIONS
ttyp_not_found = 1
name_inconsistent = 2
ttyp_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_TTYP_PUT' ).
ENDIF.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESDICT'
iv_argument = |{ ms_item-obj_type }{ ms_item-obj_name }| ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_TRAN IMPLEMENTATION.
METHOD deserialize_texts.
DATA lt_tpool_i18n TYPE TABLE OF tstct.
FIELD-SYMBOLS <ls_tpool> LIKE LINE OF lt_tpool_i18n.
" Read XML-files data
io_xml->read( EXPORTING iv_name = 'I18N_TPOOL'
CHANGING cg_data = lt_tpool_i18n ).
" Force t-code name (security reasons)
LOOP AT lt_tpool_i18n ASSIGNING <ls_tpool>.
<ls_tpool>-tcode = ms_item-obj_name.
ENDLOOP.
IF lines( lt_tpool_i18n ) > 0.
MODIFY tstct FROM TABLE lt_tpool_i18n.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Update of t-code translations failed' ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD serialize_texts.
DATA lt_tpool_i18n TYPE TABLE OF tstct.
" Skip master language - it was already serialized
" Don't serialize t-code itself
SELECT sprsl ttext
INTO CORRESPONDING FIELDS OF TABLE lt_tpool_i18n
FROM tstct
WHERE sprsl <> mv_language
AND tcode = ms_item-obj_name. "#EC CI_GENBUFF
IF lines( lt_tpool_i18n ) > 0.
SORT lt_tpool_i18n BY sprsl ASCENDING.
io_xml->add( iv_name = 'I18N_TPOOL'
ig_data = lt_tpool_i18n ).
ENDIF.
ENDMETHOD.
METHOD split_parameters.
DATA: lv_off TYPE i,
lv_param_beg TYPE i,
lv_length TYPE i,
ls_param LIKE LINE OF ct_rsparam.
FIELD-SYMBOLS <lg_f> TYPE any.
CLEAR cs_rsstcd-s_vari.
IF cs_tstcp-param(1) = '\'. " OO-Transaktion ohne FR
split_parameters_comp( EXPORTING ig_type = c_oo_program
ig_param = cs_tstcp-param
CHANGING cg_value = cs_tstc-pgmna ).
split_parameters_comp( EXPORTING ig_type = c_oo_class
ig_param = cs_tstcp-param
CHANGING cg_value = cs_rsstcd-classname ).
split_parameters_comp( EXPORTING ig_type = c_oo_method
ig_param = cs_tstcp-param
CHANGING cg_value = cs_rsstcd-method ).
IF NOT cs_tstc-pgmna IS INITIAL.
cs_rsstcd-s_local = c_true.
ENDIF.
RETURN.
ELSEIF cs_tstcp-param(1) = '@'. " Transaktionsvariante
cs_rsstcd-s_vari = c_true.
IF cs_tstcp-param(2) = '@@'.
cs_rsstcd-s_ind_vari = c_true.
lv_off = 2.
ELSE.
CLEAR cs_rsstcd-s_ind_vari.
lv_off = 1.
ENDIF.
IF cs_tstcp-param CA ' '.
ENDIF.
sy-fdpos = sy-fdpos - lv_off.
IF sy-fdpos > 0.
cs_rsstcd-call_tcode = cs_tstcp-param+lv_off(sy-fdpos).
sy-fdpos = sy-fdpos + 1 + lv_off.
cs_rsstcd-variant = cs_tstcp-param+sy-fdpos.
ENDIF.
ELSEIF cs_tstcp-param(1) = '/'.
cs_rsstcd-st_tcode = c_true.
cs_rsstcd-st_prog = space.
IF cs_tstcp-param+1(1) = '*'.
cs_rsstcd-st_skip_1 = c_true.
ELSE.
CLEAR cs_rsstcd-st_skip_1.
ENDIF.
IF cs_tstcp-param CA ' '.
ENDIF.
lv_param_beg = sy-fdpos + 1.
sy-fdpos = sy-fdpos - 2.
IF sy-fdpos > 0.
cs_rsstcd-call_tcode = cs_tstcp-param+2(sy-fdpos).
ENDIF.
SHIFT cs_tstcp-param BY lv_param_beg PLACES.
ELSE.
cs_rsstcd-st_tcode = space.
cs_rsstcd-st_prog = c_true.
ENDIF.
DO 254 TIMES.
IF cs_tstcp-param = space.
EXIT.
ENDIF.
CLEAR ls_param.
IF cs_tstcp-param CA '='.
CHECK sy-fdpos <> 0.
ASSIGN cs_tstcp-param(sy-fdpos) TO <lg_f>.
ls_param-field = <lg_f>.
IF ls_param-field(1) = space.
SHIFT ls_param-field.
ENDIF.
sy-fdpos = sy-fdpos + 1.
SHIFT cs_tstcp-param BY sy-fdpos PLACES.
IF cs_tstcp-param CA ';'.
IF sy-fdpos <> 0.
ASSIGN cs_tstcp-param(sy-fdpos) TO <lg_f>.
ls_param-value = <lg_f>.
IF ls_param-value(1) = space.
SHIFT ls_param-value.
ENDIF.
ENDIF.
sy-fdpos = sy-fdpos + 1.
SHIFT cs_tstcp-param BY sy-fdpos PLACES.
APPEND ls_param TO ct_rsparam.
ELSE.
lv_length = strlen( cs_tstcp-param ).
CHECK lv_length > 0.
ASSIGN cs_tstcp-param(lv_length) TO <lg_f>.
ls_param-value = <lg_f>.
IF ls_param-value(1) = space.
SHIFT ls_param-value.
ENDIF.
lv_length = lv_length + 1.
SHIFT cs_tstcp-param BY lv_length PLACES.
APPEND ls_param TO ct_rsparam.
ENDIF.
ENDIF.
ENDDO.
IF cs_rsstcd-call_tcode = c_oo_tcode.
cs_rsstcd-s_trframe = c_true.
LOOP AT ct_rsparam INTO ls_param.
CASE ls_param-field.
WHEN c_oo_frclass.
cs_rsstcd-classname = ls_param-value.
WHEN c_oo_frmethod.
cs_rsstcd-method = ls_param-value.
WHEN c_oo_frupdtask.
IF ls_param-value = c_oo_synchron.
cs_rsstcd-s_upddir = c_true.
cs_rsstcd-s_updtask = c_false.
cs_rsstcd-s_updlok = c_false.
ELSEIF ls_param-value = c_oo_asynchron.
cs_rsstcd-s_upddir = c_false.
cs_rsstcd-s_updtask = c_true.
cs_rsstcd-s_updlok = c_false.
ELSE.
cs_rsstcd-s_upddir = c_false.
cs_rsstcd-s_updtask = c_false.
cs_rsstcd-s_updlok = c_true.
ENDIF.
ENDCASE.
ENDLOOP.
ENDIF.
ENDMETHOD.
METHOD split_parameters_comp.
DATA: lv_off TYPE i.
IF ig_param CS ig_type.
lv_off = sy-fdpos + strlen( ig_type ).
cg_value = ig_param+lv_off.
IF cg_value CA '\'.
CLEAR cg_value+sy-fdpos.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_transaction TYPE tstc-tcode.
lv_transaction = ms_item-obj_name.
CALL FUNCTION 'RPY_TRANSACTION_DELETE'
EXPORTING
transaction = lv_transaction
EXCEPTIONS
not_excecuted = 1
object_not_found = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RPY_TRANSACTION_DELETE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
CONSTANTS: lc_hex_tra TYPE x VALUE '00',
lc_hex_par TYPE x VALUE '02',
lc_hex_rep TYPE x VALUE '80'.
DATA: lv_dynpro TYPE d020s-dnum,
ls_tstc TYPE tstc,
lv_type TYPE rglif-docutype,
ls_tstct TYPE tstct,
ls_tstcc TYPE tstcc,
ls_tstcp TYPE tstcp,
lt_param_values TYPE TABLE OF rsparam,
ls_rsstcd TYPE rsstcd.
IF zif_abapgit_object~exists( ) = abap_true.
zif_abapgit_object~delete( ).
ENDIF.
io_xml->read( EXPORTING iv_name = 'TSTC'
CHANGING cg_data = ls_tstc ).
io_xml->read( EXPORTING iv_name = 'TSTCC'
CHANGING cg_data = ls_tstcc ).
io_xml->read( EXPORTING iv_name = 'TSTCT'
CHANGING cg_data = ls_tstct ).
io_xml->read( EXPORTING iv_name = 'TSTCP'
CHANGING cg_data = ls_tstcp ).
lv_dynpro = ls_tstc-dypno.
CASE ls_tstc-cinfo.
WHEN lc_hex_tra.
lv_type = ststc_c_type_dialog.
WHEN lc_hex_rep.
lv_type = ststc_c_type_report.
WHEN lc_hex_par.
lv_type = ststc_c_type_parameters.
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'Transaction, unknown CINFO' ).
ENDCASE.
IF ls_tstcp IS NOT INITIAL.
split_parameters(
CHANGING
ct_rsparam = lt_param_values
cs_rsstcd = ls_rsstcd
cs_tstcp = ls_tstcp
cs_tstc = ls_tstc ).
ENDIF.
CALL FUNCTION 'RPY_TRANSACTION_INSERT'
EXPORTING
transaction = ls_tstc-tcode
program = ls_tstc-pgmna
dynpro = lv_dynpro
language = mv_language
development_class = iv_package
transaction_type = lv_type
shorttext = ls_tstct-ttext
called_transaction = ls_rsstcd-call_tcode
called_transaction_skip = ls_rsstcd-st_skip_1
variant = ls_rsstcd-variant
cl_independend = ls_rsstcd-s_ind_vari
html_enabled = ls_tstcc-s_webgui
java_enabled = ls_tstcc-s_platin
wingui_enabled = ls_tstcc-s_win32
TABLES
param_values = lt_param_values
EXCEPTIONS
cancelled = 1
already_exist = 2
permission_error = 3
name_not_allowed = 4
name_conflict = 5
illegal_type = 6
object_inconsistent = 7
db_access_error = 8
OTHERS = 9.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RPY_TRANSACTION_INSERT' ).
ENDIF.
" Texts deserializing (translations)
deserialize_texts( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_tcode TYPE tstc-tcode.
SELECT SINGLE tcode FROM tstc INTO lv_tcode
WHERE tcode = ms_item-obj_name. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lt_bdcdata TYPE TABLE OF bdcdata.
FIELD-SYMBOLS: <ls_bdcdata> LIKE LINE OF lt_bdcdata.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-program = 'SAPLSEUK'.
<ls_bdcdata>-dynpro = '0390'.
<ls_bdcdata>-dynbegin = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BDC_OKCODE'.
<ls_bdcdata>-fval = '=SHOW'.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'TSTC-TCODE'.
<ls_bdcdata>-fval = ms_item-obj_name.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SE93'
mode_val = 'E'
TABLES
using_tab = lt_bdcdata
EXCEPTIONS
system_failure = 1
communication_failure = 2
resource_failure = 3
OTHERS = 4
##fm_subrc_ok. "#EC CI_SUBRC
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_transaction TYPE tstc-tcode,
lt_tcodes TYPE TABLE OF tstc,
ls_tcode LIKE LINE OF lt_tcodes,
ls_tstct TYPE tstct,
ls_tstcp TYPE tstcp,
lt_gui_attr TYPE TABLE OF tstcc,
ls_gui_attr LIKE LINE OF lt_gui_attr.
lv_transaction = ms_item-obj_name.
CALL FUNCTION 'RPY_TRANSACTION_READ'
EXPORTING
transaction = lv_transaction
TABLES
tcodes = lt_tcodes
gui_attributes = lt_gui_attr
EXCEPTIONS
permission_error = 1
cancelled = 2
not_found = 3
object_not_found = 4
OTHERS = 5.
IF sy-subrc = 4 OR sy-subrc = 3.
RETURN.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RPY_TRANSACTION_READ' ).
ENDIF.
SELECT SINGLE * FROM tstct INTO ls_tstct
WHERE sprsl = mv_language
AND tcode = lv_transaction. "#EC CI_SUBRC "#EC CI_GENBUFF
SELECT SINGLE * FROM tstcp INTO ls_tstcp
WHERE tcode = lv_transaction. "#EC CI_SUBRC "#EC CI_GENBUFF
READ TABLE lt_tcodes INDEX 1 INTO ls_tcode.
ASSERT sy-subrc = 0.
READ TABLE lt_gui_attr INDEX 1 INTO ls_gui_attr.
ASSERT sy-subrc = 0.
io_xml->add( iv_name = 'TSTC'
ig_data = ls_tcode ).
io_xml->add( iv_name = 'TSTCC'
ig_data = ls_gui_attr ).
io_xml->add( iv_name = 'TSTCT'
ig_data = ls_tstct ).
IF ls_tstcp IS NOT INITIAL.
io_xml->add( iv_name = 'TSTCP'
ig_data = ls_tstcp ).
ENDIF.
" Texts serializing (translations)
serialize_texts( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE eqegraarg.
lv_object = |TN{ ms_item-obj_name }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'EEUDB'
iv_argument = lv_object ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_tobj IMPLEMENTATION.
METHOD read_extra.
SELECT SINGLE * FROM tddat INTO rs_tobj-tddat WHERE tabname = iv_tabname.
SELECT SINGLE * FROM tvdir INTO rs_tobj-tvdir WHERE tabname = iv_tabname.
CLEAR: rs_tobj-tvdir-gendate, rs_tobj-tvdir-gentime.
SELECT * FROM tvimf INTO TABLE rs_tobj-tvimf WHERE tabname = iv_tabname.
ENDMETHOD.
METHOD update_extra.
MODIFY tddat FROM is_tobj-tddat.
MODIFY tvdir FROM is_tobj-tvdir.
MODIFY tvimf FROM TABLE is_tobj-tvimf.
ENDMETHOD.
METHOD delete_extra.
DELETE FROM tddat WHERE tabname = iv_tabname.
DELETE FROM tvdir WHERE tabname = iv_tabname.
DELETE FROM tvimf WHERE tabname = iv_tabname.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lv_type_pos TYPE i.
lv_type_pos = strlen( ms_item-obj_name ) - 1.
SELECT SINGLE luser FROM objh INTO rv_user
WHERE objectname = ms_item-obj_name(lv_type_pos)
AND objecttype = ms_item-obj_name+lv_type_pos. "#EC CI_GENBUFF
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-late_deser = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_objectname TYPE objh-objectname,
lv_type_pos TYPE i.
lv_type_pos = strlen( ms_item-obj_name ) - 1.
SELECT SINGLE objectname FROM objh INTO lv_objectname
WHERE objectname = ms_item-obj_name(lv_type_pos)
AND objecttype = ms_item-obj_name+lv_type_pos. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_objh TYPE objh,
ls_objt TYPE objt,
lt_objs TYPE tt_objs,
lt_objsl TYPE tt_objsl,
lt_objm TYPE tt_objm,
ls_tobj TYPE ty_tobj,
lv_type_pos TYPE i.
lv_type_pos = strlen( ms_item-obj_name ) - 1.
ls_objh-objectname = ms_item-obj_name(lv_type_pos).
ls_objh-objecttype = ms_item-obj_name+lv_type_pos.
CALL FUNCTION 'CTO_OBJECT_GET'
EXPORTING
iv_objectname = ls_objh-objectname
iv_objecttype = ls_objh-objecttype
iv_language = mv_language
iv_sel_objt = abap_true
iv_sel_objs = abap_true
iv_sel_objsl = abap_true
iv_sel_objm = abap_true
IMPORTING
es_objh = ls_objh
es_objt = ls_objt
TABLES
tt_objs = lt_objs
tt_objsl = lt_objsl
tt_objm = lt_objm
EXCEPTIONS
object_not_defined = 1
OTHERS = 2.
IF sy-subrc = 1.
RETURN.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from CTO_OBJECT_GET' ).
ENDIF.
CLEAR: ls_objh-luser,
ls_objh-ldate.
io_xml->add( iv_name = 'OBJH'
ig_data = ls_objh ).
io_xml->add( iv_name = 'OBJT'
ig_data = ls_objt ).
io_xml->add( iv_name = 'OBJS'
ig_data = lt_objs ).
io_xml->add( iv_name = 'OBJSL'
ig_data = lt_objsl ).
io_xml->add( iv_name = 'OBJM'
ig_data = lt_objm ).
ls_tobj = read_extra( ls_objh-objectname ).
io_xml->add( iv_name = 'TOBJ'
ig_data = ls_tobj ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_objh TYPE objh,
ls_objt TYPE objt,
lt_objs TYPE tt_objs,
lt_objsl TYPE tt_objsl,
lt_objm TYPE tt_objm,
ls_tobj TYPE ty_tobj.
io_xml->read( EXPORTING iv_name = 'OBJH'
CHANGING cg_data = ls_objh ).
io_xml->read( EXPORTING iv_name = 'OBJT'
CHANGING cg_data = ls_objt ).
io_xml->read( EXPORTING iv_name = 'OBJS'
CHANGING cg_data = lt_objs ).
io_xml->read( EXPORTING iv_name = 'OBJSL'
CHANGING cg_data = lt_objsl ).
io_xml->read( EXPORTING iv_name = 'OBJM'
CHANGING cg_data = lt_objm ).
CALL FUNCTION 'OBJ_GENERATE'
EXPORTING
iv_objectname = ls_objh-objectname
iv_objecttype = ls_objh-objecttype
iv_maint_mode = 'I'
iv_objecttext = ls_objt-ddtext
iv_objcateg = ls_objh-objcateg
iv_objtransp = ls_objh-objtransp
iv_devclass = iv_package
TABLES
tt_v_obj_s = lt_objs
tt_objm = lt_objm
EXCEPTIONS
illegal_call = 1
object_not_found = 2
generate_error = 3
transport_error = 4
object_enqueue_failed = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from OBJ_GENERATE' ).
ENDIF.
CALL FUNCTION 'OBJ_SET_IMPORTABLE'
EXPORTING
iv_objectname = ls_objh-objectname
iv_objecttype = ls_objh-objecttype
iv_importable = ls_objh-importable
EXCEPTIONS
object_not_defined = 1
invalid = 2
transport_error = 3
object_enqueue_failed = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from OBJ_SET_IMPORTABLE' ).
ENDIF.
UPDATE objh SET objtransp = ls_objh-objtransp
WHERE objectname = ls_objh-objectname
AND objecttype = ls_objh-objecttype.
io_xml->read( EXPORTING iv_name = 'TOBJ'
CHANGING cg_data = ls_tobj ).
ls_tobj-tvdir-gendate = sy-datum.
ls_tobj-tvdir-gentime = sy-uzeit.
update_extra( ls_tobj ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_objh TYPE objh,
lv_type_pos TYPE i.
lv_type_pos = strlen( ms_item-obj_name ) - 1.
ls_objh-objectname = ms_item-obj_name(lv_type_pos).
ls_objh-objecttype = ms_item-obj_name+lv_type_pos.
CALL FUNCTION 'OBJ_GENERATE'
EXPORTING
iv_objectname = ls_objh-objectname
iv_objecttype = ls_objh-objecttype
iv_maint_mode = 'D'
EXCEPTIONS
illegal_call = 1
object_not_found = 2
generate_error = 3
transport_error = 4
object_enqueue_failed = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from OBJ_GENERATE' ).
ENDIF.
delete_extra( ls_objh-objectname ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
ls_bcdata-program = 'SAPMSVIM'.
ls_bcdata-dynpro = '0050'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'VIMDYNFLDS-VIEWNAME'.
ls_bcdata-fval = substring( val = ms_item-obj_name
len = strlen( ms_item-obj_name ) - 1 ).
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'VIMDYNFLDS-ELEM_GEN'.
ls_bcdata-fval = abap_true.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=SHOW'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SE54'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, TOBJ' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_tabl_valid IMPLEMENTATION.
METHOD get_where_used_recursive.
DATA: lt_findstrings TYPE stringtab,
lt_founds TYPE STANDARD TABLE OF rsfindlst,
lt_scope TYPE tty_seu_obj,
lv_findstring LIKE LINE OF lt_findstrings.
FIELD-SYMBOLS: <ls_found> TYPE rsfindlst.
lt_scope = it_scope.
lv_findstring = iv_object_name.
INSERT lv_findstring INTO TABLE lt_findstrings.
DO iv_depth TIMES.
CLEAR: lt_founds.
CALL FUNCTION 'RS_EU_CROSSREF'
EXPORTING
i_find_obj_cls = iv_object_type
no_dialog = 'X'
TABLES
i_findstrings = lt_findstrings
o_founds = lt_founds
i_scope_object_cls = lt_scope
EXCEPTIONS
not_executed = 1
not_found = 2
illegal_object = 3
no_cross_for_this_object = 4
batch = 5
batchjob_error = 6
wrong_type = 7
object_not_exist = 8
OTHERS = 9.
IF sy-subrc = 1
OR sy-subrc = 2
OR lines( lt_founds ) = 0.
EXIT.
ELSEIF sy-subrc > 2.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
INSERT LINES OF lt_founds INTO TABLE rt_founds_all.
CLEAR: lt_findstrings.
LOOP AT lt_founds ASSIGNING <ls_found>.
lv_findstring = <ls_found>-object.
INSERT lv_findstring INTO TABLE lt_findstrings.
ENDLOOP.
ENDDO.
ENDMETHOD.
METHOD validate.
DATA: lt_previous_table_fields TYPE TABLE OF dd03p,
ls_previous_table_field LIKE LINE OF lt_previous_table_fields,
lt_current_table_fields TYPE TABLE OF dd03p,
ls_current_table_field LIKE LINE OF lt_current_table_fields,
ls_dd02v TYPE dd02v.
io_remote_version->read(
EXPORTING
iv_name = 'DD02V'
CHANGING
cg_data = ls_dd02v ).
" We only want to compare transparent tables, or structures used in transparent tables
IF ls_dd02v-tabclass <> 'TRANSP' AND is_structure_used_in_db_table( ls_dd02v-tabname ) = abap_false.
RETURN.
ENDIF.
io_remote_version->read(
EXPORTING
iv_name = 'DD03P_TABLE'
CHANGING
cg_data = lt_previous_table_fields ).
io_local_version->read(
EXPORTING
iv_name = 'DD03P_TABLE'
CHANGING
cg_data = lt_current_table_fields ).
LOOP AT lt_previous_table_fields INTO ls_previous_table_field.
READ TABLE lt_current_table_fields WITH KEY fieldname = ls_previous_table_field-fieldname
INTO ls_current_table_field.
IF sy-subrc = 0.
IF ls_current_table_field-rollname <> ls_previous_table_field-rollname.
rv_message = 'Fields were changed. This may lead to inconsistencies.'.
ENDIF.
ELSE.
rv_message = 'Fields were changed. This may lead to inconsistencies.'.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD is_structure_used_in_db_table.
DATA: lt_scope TYPE tty_seu_obj,
lt_founds TYPE tty_founds.
APPEND 'TABL' TO lt_scope.
APPEND 'STRU' TO lt_scope.
lt_founds = get_where_used_recursive( iv_object_name = iv_object_name
iv_object_type = 'STRU'
it_scope = lt_scope
iv_depth = 5 ).
DELETE lt_founds WHERE object_cls <> 'DT'.
rv_is_structure_used_in_db_tab = boolc( lines( lt_founds ) > 0 ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_TABL_DIALOG IMPLEMENTATION.
METHOD constructor.
mv_message = iv_message.
ENDMETHOD.
METHOD zif_abapgit_comparison_result~is_result_complete_halt.
rv_response = mv_halt.
ENDMETHOD.
METHOD zif_abapgit_comparison_result~show_confirmation_dialog.
DATA lv_answer TYPE string.
CALL FUNCTION 'POPUP_TO_CONFIRM'
EXPORTING
titlebar = 'Warning'
text_question = mv_message
text_button_1 = 'Abort'
icon_button_1 = 'ICON_CANCEL'
text_button_2 = 'Pull anyway'
icon_button_2 = 'ICON_OKAY'
default_button = '2'
display_cancel_button = abap_false
IMPORTING
answer = lv_answer
EXCEPTIONS
text_not_found = 1
OTHERS = 2. "#EC NOTEXT
IF sy-subrc <> 0 OR lv_answer = 1.
mv_halt = abap_true.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_tabl IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
TYPES: BEGIN OF ty_data,
as4user TYPE as4user,
as4date TYPE as4date,
as4time TYPE as4time,
END OF ty_data.
DATA: lt_data TYPE STANDARD TABLE OF ty_data WITH DEFAULT KEY,
ls_data LIKE LINE OF lt_data.
SELECT as4user as4date as4time
FROM dd02l INTO TABLE lt_data
WHERE tabname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
SELECT as4user as4date as4time
APPENDING TABLE lt_data
FROM dd09l
WHERE tabname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
SELECT as4user as4date as4time
APPENDING TABLE lt_data
FROM dd12l
WHERE sqltab = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
SORT lt_data BY as4date DESCENDING as4time DESCENDING.
READ TABLE lt_data INDEX 1 INTO ls_data.
IF sy-subrc = 0.
rv_user = ls_data-as4user.
ELSE.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
DATA: lo_table_validation TYPE REF TO zcl_abapgit_object_tabl_valid,
lo_local_version_output TYPE REF TO zcl_abapgit_xml_output,
lo_local_version_input TYPE REF TO zcl_abapgit_xml_input,
lv_validation_text TYPE string.
CREATE OBJECT lo_local_version_output.
me->zif_abapgit_object~serialize( lo_local_version_output ).
CREATE OBJECT lo_local_version_input
EXPORTING
iv_xml = lo_local_version_output->render( ).
CREATE OBJECT lo_table_validation.
lv_validation_text = lo_table_validation->validate(
io_remote_version = io_remote_version_xml
io_local_version = lo_local_version_input ).
IF lv_validation_text IS NOT INITIAL.
lv_validation_text = |Database Table { ms_item-obj_name }: { lv_validation_text }|.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_object_tabl_dialog
EXPORTING
iv_message = lv_validation_text.
ELSE.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objname TYPE rsedd0-ddobjname,
lv_tabclass TYPE dd02l-tabclass,
lv_no_ask TYPE abap_bool,
lv_subrc TYPE sy-subrc,
lr_data TYPE REF TO data.
FIELD-SYMBOLS: <lg_data> TYPE any.
lv_objname = ms_item-obj_name.
lv_no_ask = abap_true.
SELECT SINGLE tabclass FROM dd02l INTO lv_tabclass
WHERE tabname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
IF sy-subrc = 0 AND lv_tabclass = 'TRANSP'.
CALL FUNCTION 'DB_EXISTS_TABLE'
EXPORTING
tabname = lv_objname
IMPORTING
subrc = lv_subrc.
IF lv_subrc = 0.
CREATE DATA lr_data TYPE (lv_objname).
ASSIGN lr_data->* TO <lg_data>.
SELECT SINGLE * FROM (lv_objname) INTO <lg_data>.
IF sy-subrc = 0.
lv_no_ask = abap_false.
ENDIF.
ENDIF.
ENDIF.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = lv_no_ask
objname = lv_objname
objtype = 'T'
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, TABL' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_name TYPE ddobjname,
lv_tname TYPE trobj_name,
ls_dd02v TYPE dd02v,
ls_dd09l TYPE dd09l,
lt_dd03p TYPE TABLE OF dd03p,
lt_dd05m TYPE TABLE OF dd05m,
lt_dd08v TYPE TABLE OF dd08v,
lt_dd12v TYPE dd12vtab,
lt_dd17v TYPE dd17vtab,
ls_dd17v LIKE LINE OF lt_dd17v,
lt_secondary LIKE lt_dd17v,
lt_dd35v TYPE TABLE OF dd35v,
lt_dd36m TYPE dd36mttyp,
ls_dd12v LIKE LINE OF lt_dd12v.
io_xml->read( EXPORTING iv_name = 'DD02V'
CHANGING cg_data = ls_dd02v ).
io_xml->read( EXPORTING iv_name = 'DD09L'
CHANGING cg_data = ls_dd09l ).
io_xml->read( EXPORTING iv_name = 'DD03P_TABLE'
CHANGING cg_data = lt_dd03p ).
io_xml->read( EXPORTING iv_name = 'DD05M_TABLE'
CHANGING cg_data = lt_dd05m ).
io_xml->read( EXPORTING iv_name = 'DD08V_TABLE'
CHANGING cg_data = lt_dd08v ).
io_xml->read( EXPORTING iv_name = 'DD12V'
CHANGING cg_data = lt_dd12v ).
io_xml->read( EXPORTING iv_name = 'DD17V'
CHANGING cg_data = lt_dd17v ).
io_xml->read( EXPORTING iv_name = 'DD35V_TALE'
CHANGING cg_data = lt_dd35v ).
io_xml->read( EXPORTING iv_name = 'DD36M'
CHANGING cg_data = lt_dd36m ).
corr_insert( iv_package ).
lv_name = ms_item-obj_name. " type conversion
CALL FUNCTION 'DDIF_TABL_PUT'
EXPORTING
name = lv_name
dd02v_wa = ls_dd02v
dd09l_wa = ls_dd09l
TABLES
dd03p_tab = lt_dd03p
dd05m_tab = lt_dd05m
dd08v_tab = lt_dd08v
dd35v_tab = lt_dd35v
dd36m_tab = lt_dd36m
EXCEPTIONS
tabl_not_found = 1
name_inconsistent = 2
tabl_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_TABL_PUT' ).
ENDIF.
zcl_abapgit_objects_activation=>add_item( ms_item ).
LOOP AT lt_dd12v INTO ls_dd12v.
CLEAR lt_secondary.
LOOP AT lt_dd17v INTO ls_dd17v
WHERE sqltab = ls_dd12v-sqltab AND indexname = ls_dd12v-indexname.
APPEND ls_dd17v TO lt_secondary.
ENDLOOP.
CALL FUNCTION 'DDIF_INDX_PUT'
EXPORTING
name = ls_dd12v-sqltab
id = ls_dd12v-indexname
dd12v_wa = ls_dd12v
TABLES
dd17v_tab = lt_secondary
EXCEPTIONS
indx_not_found = 1
name_inconsistent = 2
indx_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_INDX_PUT' ).
ENDIF.
CALL FUNCTION 'DD_DD_TO_E071'
EXPORTING
type = 'INDX'
name = ls_dd12v-sqltab
id = ls_dd12v-indexname
IMPORTING
obj_name = lv_tname.
zcl_abapgit_objects_activation=>add( iv_type = 'INDX'
iv_name = lv_tname ).
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_tabname TYPE dd02l-tabname.
SELECT SINGLE tabname FROM dd02l INTO lv_tabname
WHERE tabname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA: lv_date TYPE dats,
lv_time TYPE tims,
lt_indexes TYPE STANDARD TABLE OF dd09l.
FIELD-SYMBOLS <ls_index> LIKE LINE OF lt_indexes.
SELECT SINGLE as4date as4time FROM dd02l " Table
INTO (lv_date, lv_time)
WHERE tabname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
SELECT SINGLE as4date as4time FROM dd09l " Table tech settings
INTO (lv_date, lv_time)
WHERE tabname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
SELECT as4date as4time FROM dd12l " Table tech settings
INTO CORRESPONDING FIELDS OF TABLE lt_indexes
WHERE sqltab = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'
ORDER BY PRIMARY KEY ##TOO_MANY_ITAB_FIELDS.
LOOP AT lt_indexes ASSIGNING <ls_index>.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = <ls_index>-as4date
iv_time = <ls_index>-as4time ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESDICT'
iv_argument = |{ ms_item-obj_type }{ ms_item-obj_name }| ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
jump_se11( iv_radio = 'RSRD1-DDTYPE'
iv_field = 'RSRD1-DDTYPE_VAL' ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_name TYPE ddobjname,
ls_dd02v TYPE dd02v,
ls_dd09l TYPE dd09l,
lt_dd03p TYPE TABLE OF dd03p,
lt_dd05m TYPE TABLE OF dd05m,
lt_dd08v TYPE TABLE OF dd08v,
lt_dd12v TYPE dd12vtab,
lt_dd17v TYPE dd17vtab,
lt_dd35v TYPE TABLE OF dd35v,
lv_index LIKE sy-index,
lv_masklen TYPE c LENGTH 4,
lt_dd36m TYPE dd36mttyp.
FIELD-SYMBOLS: <ls_dd12v> LIKE LINE OF lt_dd12v,
<ls_dd05m> LIKE LINE OF lt_dd05m,
<ls_dd36m> LIKE LINE OF lt_dd36m,
<ls_dd03p> LIKE LINE OF lt_dd03p,
<lg_roworcolst> TYPE any.
lv_name = ms_item-obj_name.
CALL FUNCTION 'DDIF_TABL_GET'
EXPORTING
name = lv_name
langu = mv_language
IMPORTING
dd02v_wa = ls_dd02v
dd09l_wa = ls_dd09l
TABLES
dd03p_tab = lt_dd03p
dd05m_tab = lt_dd05m
dd08v_tab = lt_dd08v
dd12v_tab = lt_dd12v
dd17v_tab = lt_dd17v
dd35v_tab = lt_dd35v
dd36m_tab = lt_dd36m
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_TABL_GET' ).
ENDIF.
IF ls_dd02v IS INITIAL.
RETURN. " object does not exits
ENDIF.
CLEAR: ls_dd02v-as4user,
ls_dd02v-as4date,
ls_dd02v-as4time.
IF ls_dd02v-prozpuff = ''.
CLEAR ls_dd02v-prozpuff.
ENDIF.
IF ls_dd02v-datmin = ''.
CLEAR ls_dd02v-datmin.
ENDIF.
IF ls_dd02v-datmax = ''.
CLEAR ls_dd02v-datmax.
ENDIF.
IF ls_dd02v-datavg = ''.
CLEAR ls_dd02v-datavg.
ENDIF.
CLEAR: ls_dd09l-as4user,
ls_dd09l-as4date,
ls_dd09l-as4time.
ASSIGN COMPONENT 'ROWORCOLST' OF STRUCTURE ls_dd09l TO <lg_roworcolst>.
IF sy-subrc = 0 AND <lg_roworcolst> = 'C'.
CLEAR <lg_roworcolst>. "To avoid diff errors. This field doesn't exists in all releases
ENDIF.
LOOP AT lt_dd12v ASSIGNING <ls_dd12v>.
CLEAR: <ls_dd12v>-as4user,
<ls_dd12v>-as4date,
<ls_dd12v>-as4time.
ENDLOOP.
DELETE lt_dd03p WHERE depth <> '00'.
DELETE lt_dd03p WHERE adminfield <> '0'.
LOOP AT lt_dd03p ASSIGNING <ls_dd03p> WHERE NOT rollname IS INITIAL.
CLEAR: <ls_dd03p>-ddlanguage,
<ls_dd03p>-dtelmaster,
<ls_dd03p>-logflag,
<ls_dd03p>-ddtext,
<ls_dd03p>-reservedte,
<ls_dd03p>-reptext,
<ls_dd03p>-scrtext_s,
<ls_dd03p>-scrtext_m,
<ls_dd03p>-scrtext_l.
lv_masklen = <ls_dd03p>-masklen.
IF lv_masklen = '' OR NOT lv_masklen CO '0123456789'.
CLEAR <ls_dd03p>-masklen.
ENDIF.
IF <ls_dd03p>-comptype = 'E'.
CLEAR: <ls_dd03p>-domname,
<ls_dd03p>-inttype,
<ls_dd03p>-intlen,
<ls_dd03p>-mask,
<ls_dd03p>-memoryid,
<ls_dd03p>-headlen,
<ls_dd03p>-scrlen1,
<ls_dd03p>-scrlen2,
<ls_dd03p>-scrlen3,
<ls_dd03p>-datatype,
<ls_dd03p>-leng,
<ls_dd03p>-outputlen,
<ls_dd03p>-deffdname,
<ls_dd03p>-convexit,
<ls_dd03p>-entitytab,
<ls_dd03p>-dommaster,
<ls_dd03p>-domname3l,
<ls_dd03p>-decimals,
<ls_dd03p>-lowercase,
<ls_dd03p>-signflag.
ENDIF.
IF <ls_dd03p>-shlporigin = 'D'.
CLEAR: <ls_dd03p>-shlpfield,
<ls_dd03p>-shlpname.
ENDIF.
IF <ls_dd03p>-routputlen = ' '.
CLEAR <ls_dd03p>-routputlen.
ENDIF.
ENDLOOP.
DELETE lt_dd08v WHERE noinherit = 'N'.
LOOP AT lt_dd05m ASSIGNING <ls_dd05m>.
lv_index = sy-tabix.
READ TABLE lt_dd08v WITH KEY fieldname = <ls_dd05m>-fieldname TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
DELETE lt_dd05m INDEX lv_index.
ENDIF.
ENDLOOP.
DELETE lt_dd35v WHERE shlpinher = abap_true.
LOOP AT lt_dd36m ASSIGNING <ls_dd36m>.
lv_index = sy-tabix.
READ TABLE lt_dd35v WITH KEY fieldname = <ls_dd36m>-fieldname TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
DELETE lt_dd36m INDEX lv_index.
ENDIF.
ENDLOOP.
io_xml->add( iv_name = 'DD02V'
ig_data = ls_dd02v ).
IF NOT ls_dd09l IS INITIAL.
io_xml->add( iv_name = 'DD09L'
ig_data = ls_dd09l ).
ENDIF.
io_xml->add( ig_data = lt_dd03p
iv_name = 'DD03P_TABLE' ).
io_xml->add( ig_data = lt_dd05m
iv_name = 'DD05M_TABLE' ).
io_xml->add( ig_data = lt_dd08v
iv_name = 'DD08V_TABLE' ).
io_xml->add( iv_name = 'DD12V'
ig_data = lt_dd12v ).
io_xml->add( iv_name = 'DD17V'
ig_data = lt_dd17v ).
io_xml->add( ig_data = lt_dd35v
iv_name = 'DD35V_TALE' ).
io_xml->add( iv_name = 'DD36M'
ig_data = lt_dd36m ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_SXCI IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_implementation_name TYPE rsexscrn-imp_name.
lv_implementation_name = ms_item-obj_name.
CALL FUNCTION 'SXO_IMPL_DELETE'
EXPORTING
imp_name = lv_implementation_name
no_dialog = abap_true
EXCEPTIONS
imp_not_existing = 1
action_canceled = 2
access_failure = 3
data_inconsistency = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SXO_IMPL_DELETE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_badi_definition TYPE badi_data,
lo_filter_object TYPE REF TO cl_badi_flt_struct,
lo_filter_values_object TYPE REF TO cl_badi_flt_values_alv,
lv_korrnum TYPE trkorr,
lv_filter_type_enhanceability TYPE rsexscrn-flt_ext,
lv_package TYPE devclass,
ls_classic_badi_implementation TYPE ty_classic_badi_implementation.
io_xml->read(
EXPORTING
iv_name = 'SXCI'
CHANGING
cg_data = ls_classic_badi_implementation ).
CALL FUNCTION 'SXO_BADI_READ'
EXPORTING
exit_name = ls_classic_badi_implementation-implementation_data-exit_name
IMPORTING
badi = ls_badi_definition
filter_obj = lo_filter_object
EXCEPTIONS
read_failure = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SXO_BADI_READ' ).
ENDIF.
lv_package = iv_package.
CREATE OBJECT lo_filter_values_object
EXPORTING
filter_object = lo_filter_object
filter_values = ls_classic_badi_implementation-filters.
CALL FUNCTION 'SXO_IMPL_SAVE'
EXPORTING
impl = ls_classic_badi_implementation-implementation_data
flt_ext = lv_filter_type_enhanceability
filter_val_obj = lo_filter_values_object
genflag = abap_true
no_dialog = abap_true
TABLES
fcodes_to_insert = ls_classic_badi_implementation-function_codes
cocos_to_insert = ls_classic_badi_implementation-control_composites
intas_to_insert = ls_classic_badi_implementation-customer_includes
sscrs_to_insert = ls_classic_badi_implementation-screens
CHANGING
korrnum = lv_korrnum
devclass = lv_package
EXCEPTIONS
save_failure = 1
action_canceled = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SXO_IMPL_SAVE' ).
ENDIF.
CALL FUNCTION 'SXO_IMPL_ACTIVE'
EXPORTING
imp_name = ls_classic_badi_implementation-implementation_data-imp_name
no_dialog = abap_true
EXCEPTIONS
badi_not_existing = 1
imp_not_existing = 2
already_active = 3
data_inconsistency = 4
activation_not_admissable = 5
action_canceled = 6
access_failure = 7
OTHERS = 8.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SXO_IMPL_ACTIVE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_implementation_name TYPE rsexscrn-imp_name.
lv_implementation_name = ms_item-obj_name.
CALL FUNCTION 'SXV_IMP_EXISTS'
EXPORTING
imp_name = lv_implementation_name
EXCEPTIONS
not_existing = 1
data_inconsistency = 2
OTHERS = 3.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
in_new_window = abap_true
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_TOOL_ACCESS' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_implementation_name TYPE rsexscrn-imp_name,
lv_exit_name TYPE rsexscrn-exit_name,
lo_filter_object TYPE REF TO cl_badi_flt_struct,
ls_badi_definition TYPE badi_data,
lo_filter_values_object TYPE REF TO cl_badi_flt_values_alv,
lt_methods TYPE seex_mtd_table,
ls_classic_badi_implementation TYPE ty_classic_badi_implementation.
lv_implementation_name = ms_item-obj_name.
CALL FUNCTION 'SXV_EXIT_FOR_IMP'
EXPORTING
imp_name = lv_implementation_name
IMPORTING
exit_name = lv_exit_name
TABLES
filters = ls_classic_badi_implementation-filters
EXCEPTIONS
data_inconsistency = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SXV_EXIT_FOR_IMP' ).
ENDIF.
CALL FUNCTION 'SXO_BADI_READ'
EXPORTING
exit_name = lv_exit_name
IMPORTING
badi = ls_badi_definition
filter_obj = lo_filter_object
TABLES
fcodes = ls_classic_badi_implementation-function_codes
cocos = ls_classic_badi_implementation-control_composites
intas = ls_classic_badi_implementation-customer_includes
scrns = ls_classic_badi_implementation-screens
methods = lt_methods
EXCEPTIONS
read_failure = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SXO_BADI_READ' ).
ENDIF.
CALL FUNCTION 'SXO_IMPL_FOR_BADI_READ'
EXPORTING
imp_name = lv_implementation_name
exit_name = lv_exit_name
inter_name = ls_badi_definition-inter_name
filter_obj = lo_filter_object
no_create_filter_values_obj = abap_true
IMPORTING
impl = ls_classic_badi_implementation-implementation_data
filter_values_obj = lo_filter_values_object
TABLES
fcodes = ls_classic_badi_implementation-function_codes
cocos = ls_classic_badi_implementation-control_composites
intas = ls_classic_badi_implementation-customer_includes
scrns = ls_classic_badi_implementation-screens
CHANGING
methods = lt_methods
EXCEPTIONS
read_failure = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SXO_IMPL_FOR_BADI_READ' ).
ENDIF.
CLEAR: ls_classic_badi_implementation-implementation_data-aname,
ls_classic_badi_implementation-implementation_data-adate,
ls_classic_badi_implementation-implementation_data-atime,
ls_classic_badi_implementation-implementation_data-uname,
ls_classic_badi_implementation-implementation_data-udate,
ls_classic_badi_implementation-implementation_data-utime,
ls_classic_badi_implementation-implementation_data-active.
io_xml->add( iv_name = 'SXCI'
ig_data = ls_classic_badi_implementation ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_suso IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_objct TYPE tobj-objct.
SELECT SINGLE objct FROM tobj INTO lv_objct
WHERE objct = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_tobj TYPE tobj,
ls_tobjt TYPE tobjt,
ls_tobjvorflg TYPE tobjvorflg,
lt_tactz TYPE TABLE OF tactz,
lt_tobjvordat TYPE TABLE OF tobjvordat,
lt_tobjvor TYPE TABLE OF tobjvor.
SELECT SINGLE * FROM tobj INTO ls_tobj
WHERE objct = ms_item-obj_name.
IF sy-subrc <> 0.
RETURN.
ENDIF.
CLEAR ls_tobj-bname.
SELECT SINGLE * FROM tobjt INTO ls_tobjt
WHERE object = ms_item-obj_name
AND langu = mv_language. "#EC CI_GENBUFF
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'TOBJT no english description'
&& ' for object (' && ms_item-obj_name && ')' ).
ENDIF.
SELECT SINGLE * FROM tobjvorflg INTO ls_tobjvorflg
WHERE objct = ms_item-obj_name. "#EC CI_SUBRC
SELECT * FROM tactz INTO TABLE lt_tactz
WHERE brobj = ms_item-obj_name
ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF
SELECT * FROM tobjvordat INTO TABLE lt_tobjvordat
WHERE objct = ms_item-obj_name
ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF
SELECT * FROM tobjvor INTO TABLE lt_tobjvor
WHERE objct = ms_item-obj_name
ORDER BY PRIMARY KEY. "#EC CI_SUBRC
io_xml->add( iv_name = 'TOBJ'
ig_data = ls_tobj ).
io_xml->add( iv_name = 'TOBJT'
ig_data = ls_tobjt ).
io_xml->add( iv_name = 'TOBJVORFLG'
ig_data = ls_tobjvorflg ).
io_xml->add( ig_data = lt_tactz
iv_name = 'TACTZ' ).
io_xml->add( ig_data = lt_tobjvordat
iv_name = 'TOBJVORDAT' ).
io_xml->add( ig_data = lt_tobjvor
iv_name = 'TOBJVOR' ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_objectname TYPE e071-obj_name,
ls_tobj TYPE tobj,
ls_tobjt TYPE tobjt,
ls_tobjvorflg TYPE tobjvorflg,
lt_tactz TYPE TABLE OF tactz,
lt_tobjvordat TYPE TABLE OF tobjvordat,
lt_tobjvor TYPE TABLE OF tobjvor.
ASSERT NOT ms_item-obj_name IS INITIAL.
io_xml->read( EXPORTING iv_name = 'TOBJ'
CHANGING cg_data = ls_tobj ).
ls_tobj-bname = sy-uname.
io_xml->read( EXPORTING iv_name = 'TOBJT'
CHANGING cg_data = ls_tobjt ).
io_xml->read( EXPORTING iv_name = 'TOBJVORFLG'
CHANGING cg_data = ls_tobjvorflg ).
io_xml->read( EXPORTING iv_name = 'TACTZ'
CHANGING cg_data = lt_tactz ).
io_xml->read( EXPORTING iv_name = 'TOBJVORDAT'
CHANGING cg_data = lt_tobjvordat ).
io_xml->read( EXPORTING iv_name = 'TOBJVOR'
CHANGING cg_data = lt_tobjvor ).
tadir_insert( iv_package ).
lv_objectname = ms_item-obj_name.
CALL FUNCTION 'SUSR_COMMEDITCHECK'
EXPORTING
objectname = lv_objectname
transobjecttype = 'O'.
MODIFY tobj FROM ls_tobj. "#EC CI_SUBRC
MODIFY tobjt FROM ls_tobjt. "#EC CI_SUBRC
MODIFY tobjvorflg FROM ls_tobjvorflg. "#EC CI_SUBRC
DELETE FROM tactz WHERE brobj = ms_item-obj_name. "#EC CI_SUBRC
INSERT tactz FROM TABLE lt_tactz. "#EC CI_SUBRC
DELETE FROM tobjvordat WHERE objct = ms_item-obj_name. "#EC CI_SUBRC
INSERT tobjvordat FROM TABLE lt_tobjvordat. "#EC CI_SUBRC
DELETE FROM tobjvor WHERE objct = ms_item-obj_name. "#EC CI_SUBRC
INSERT tobjvor FROM TABLE lt_tobjvor. "#EC CI_SUBRC
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_object TYPE tobj-objct.
lv_object = ms_item-obj_name.
CALL FUNCTION 'SUSR_DELETE_OBJECT'
EXPORTING
object = lv_object.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lv_object TYPE tobj-objct.
lv_object = ms_item-obj_name.
CALL FUNCTION 'SUSR_SHOW_OBJECT'
EXPORTING
object = lv_object.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_susc IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_oclss TYPE tobc-oclss.
SELECT SINGLE oclss FROM tobc INTO lv_oclss
WHERE oclss = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_tobc TYPE tobc,
ls_tobct TYPE tobct.
SELECT SINGLE * FROM tobc INTO ls_tobc
WHERE oclss = ms_item-obj_name.
IF sy-subrc <> 0.
RETURN.
ENDIF.
SELECT SINGLE * FROM tobct INTO ls_tobct
WHERE oclss = ms_item-obj_name
AND langu = mv_language.
io_xml->add( iv_name = 'TOBC'
ig_data = ls_tobc ).
io_xml->add( iv_name = 'TOBCT'
ig_data = ls_tobct ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_tobc TYPE tobc,
lv_objectname TYPE e071-obj_name,
ls_tobct TYPE tobct.
io_xml->read( EXPORTING iv_name = 'TOBC'
CHANGING cg_data = ls_tobc ).
io_xml->read( EXPORTING iv_name = 'TOBCT'
CHANGING cg_data = ls_tobct ).
tadir_insert( iv_package ).
lv_objectname = ms_item-obj_name.
CALL FUNCTION 'SUSR_COMMEDITCHECK'
EXPORTING
objectname = lv_objectname
transobjecttype = 'C'.
INSERT tobc FROM ls_tobc. "#EC CI_SUBRC
MODIFY tobct FROM ls_tobct. "#EC CI_SUBRC
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objclass TYPE tobc-oclss.
lv_objclass = ms_item-obj_name.
CALL FUNCTION 'SUSR_DELETE_OBJECT_CLASS'
EXPORTING
objclass = lv_objclass.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lv_objclass TYPE tobc-oclss.
lv_objclass = ms_item-obj_name.
CALL FUNCTION 'SUSR_SHOW_OBJECT_CLASS'
EXPORTING
objclass = lv_objclass.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_styl IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_style TYPE ty_style,
lv_name TYPE itcda-tdstyle.
lv_name = ms_item-obj_name.
CALL FUNCTION 'READ_STYLE'
EXPORTING
style = lv_name
IMPORTING
style_header = ls_style-header
TABLES
paragraphs = ls_style-paragraphs
strings = ls_style-strings
tabs = ls_style-tabs.
rv_user = ls_style-header-tdluser.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_style TYPE ty_style,
lv_name TYPE itcda-tdstyle,
lv_found TYPE abap_bool.
lv_name = ms_item-obj_name.
CALL FUNCTION 'READ_STYLE'
EXPORTING
style = lv_name
IMPORTING
found = lv_found
TABLES
paragraphs = ls_style-paragraphs
strings = ls_style-strings
tabs = ls_style-tabs.
rv_bool = boolc( lv_found = abap_true ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
ls_bcdata-program = 'SAPMSSCS'.
ls_bcdata-dynpro = '1100'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'RSSCS-TDSTYLE'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'RSSCS-TDSPRAS'.
ls_bcdata-fval = sy-langu.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'RSSCS-TDHEADEROB'.
ls_bcdata-fval = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=SHOW'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SE72'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, STYL' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_style TYPE itcda-tdstyle.
lv_style = ms_item-obj_name.
CALL FUNCTION 'DELETE_STYLE'
EXPORTING
style = lv_style
language = '*'.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_style TYPE ty_style.
io_xml->read( EXPORTING iv_name = 'STYLE'
CHANGING cg_data = ls_style ).
CALL FUNCTION 'SAVE_STYLE'
EXPORTING
style_header = ls_style-header
TABLES
paragraphs = ls_style-paragraphs
strings = ls_style-strings
tabs = ls_style-tabs.
tadir_insert( iv_package ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_style TYPE ty_style,
lv_name TYPE itcda-tdstyle.
lv_name = ms_item-obj_name.
CALL FUNCTION 'READ_STYLE'
EXPORTING
style = lv_name
IMPORTING
style_header = ls_style-header
TABLES
paragraphs = ls_style-paragraphs
strings = ls_style-strings
tabs = ls_style-tabs.
CLEAR: ls_style-header-tdfuser,
ls_style-header-tdfdate,
ls_style-header-tdftime,
ls_style-header-tdfreles,
ls_style-header-tdluser,
ls_style-header-tdldate,
ls_style-header-tdltime,
ls_style-header-tdlreles.
io_xml->add( iv_name = 'STYLE'
ig_data = ls_style ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ssst IMPLEMENTATION.
METHOD validate_font.
DATA: lv_tdfamily TYPE tfo01-tdfamily.
SELECT SINGLE tdfamily FROM tfo01 INTO lv_tdfamily
WHERE tdfamily = iv_tdfamily.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Font family not found' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE lastuser FROM stxsadm INTO rv_user
WHERE stylename = ms_item-obj_name.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_stylename TYPE tdssname.
lv_stylename = ms_item-obj_name.
CALL FUNCTION 'SSF_DELETE_STYLE'
EXPORTING
i_stylename = lv_stylename
i_with_dialog = abap_false
i_with_confirm_dialog = abap_false
EXCEPTIONS
no_name = 1
no_style = 2
style_locked = 3
cancelled = 4
no_access_permission = 5
illegal_language = 6
OTHERS = 7.
IF sy-subrc <> 0 AND sy-subrc <> 2.
zcx_abapgit_exception=>raise( 'error from SSF_DELETE_STYLE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_header TYPE ssfcats,
ls_new_header TYPE ssfcats,
lt_paragraphs TYPE TABLE OF ssfparas,
lt_strings TYPE TABLE OF ssfstrings,
lt_tabstops TYPE TABLE OF stxstab.
FIELD-SYMBOLS: <lv_spras> TYPE spras.
io_xml->read( EXPORTING iv_name = 'HEADER'
CHANGING cg_data = ls_header ).
io_xml->read( EXPORTING iv_name = 'SSFPARAS'
CHANGING cg_data = lt_paragraphs ).
io_xml->read( EXPORTING iv_name = 'SSFSTRINGS'
CHANGING cg_data = lt_strings ).
io_xml->read( EXPORTING iv_name = 'STXSTAB'
CHANGING cg_data = lt_tabstops ).
validate_font( ls_header-tdfamily ).
CALL FUNCTION 'SSF_READ_STYLE' "Just load FG
EXPORTING
i_style_name = ls_header-stylename
i_style_active_flag = 'A'
EXCEPTIONS
OTHERS = 0.
set_default_package( iv_package ).
ASSIGN ('(SAPLSTXBS)MASTER_LANGUAGE') TO <lv_spras>.
IF sy-subrc = 0.
<lv_spras> = ls_header-masterlang.
ENDIF.
tadir_insert( iv_package ).
CALL FUNCTION 'SSF_SAVE_STYLE'
EXPORTING
i_header = ls_header
IMPORTING
e_header = ls_new_header
TABLES
i_paragraphs = lt_paragraphs
i_strings = lt_strings
i_tabstops = lt_tabstops.
IF ls_new_header IS NOT INITIAL.
CALL FUNCTION 'SSF_ACTIVATE_STYLE'
EXPORTING
i_stylename = ls_header-stylename
EXCEPTIONS
no_name = 1
no_style = 2
cancelled = 3
no_access_permission = 4
illegal_language = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SSF_ACTIVATE_STYLE' ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_stylename TYPE stxsadm-stylename.
SELECT SINGLE stylename
FROM stxshead INTO lv_stylename
WHERE active = c_style_active
AND stylename = ms_item-obj_name
AND vari = ''.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
ls_bcdata-program = 'SAPMSSFS'.
ls_bcdata-dynpro = '0100'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'SSFSCREENS-SNAME'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=DISPLAY'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SMARTSTYLES'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SSST' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_style_name TYPE tdssname,
ls_header TYPE ssfcats,
lt_paragraphs TYPE TABLE OF ssfparas,
lt_strings TYPE TABLE OF ssfstrings,
lt_tabstops TYPE TABLE OF stxstab.
lv_style_name = ms_item-obj_name.
CALL FUNCTION 'SSF_READ_STYLE'
EXPORTING
i_style_name = lv_style_name
i_style_active_flag = c_style_active
i_style_variant = '%MAIN'
i_style_language = mv_language
IMPORTING
e_header = ls_header
TABLES
e_paragraphs = lt_paragraphs
e_strings = lt_strings
e_tabstops = lt_tabstops
EXCEPTIONS
no_name = 1
no_style = 2
active_style_not_found = 3
inactive_style_not_found = 4
no_variant = 5
no_main_variant = 6
cancelled = 7
no_access_permission = 8
OTHERS = 9.
IF sy-subrc = 2.
RETURN.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SSF_READ_STYLE' ).
ENDIF.
CLEAR ls_header-version.
CLEAR ls_header-firstuser.
CLEAR ls_header-firstdate.
CLEAR ls_header-firsttime.
CLEAR ls_header-lastuser.
CLEAR ls_header-lastdate.
CLEAR ls_header-lasttime.
io_xml->add( iv_name = 'HEADER'
ig_data = ls_header ).
io_xml->add( ig_data = lt_paragraphs
iv_name = 'SSFPARAS' ).
io_xml->add( ig_data = lt_strings
iv_name = 'SSFSTRINGS' ).
io_xml->add( ig_data = lt_tabstops
iv_name = 'STXSTAB' ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'E_SMSTYLE'
iv_argument = |{ ms_item-obj_name }| ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ssfo IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE lastuser FROM stxfadm INTO rv_user
WHERE formname = ms_item-obj_name.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_formname TYPE stxfadm-formname.
SELECT SINGLE formname FROM stxfadm INTO lv_formname
WHERE formname = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lt_bdcdata TYPE TABLE OF bdcdata,
lv_formtype TYPE stxfadm-formtype.
FIELD-SYMBOLS: <ls_bdcdata> LIKE LINE OF lt_bdcdata.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-program = 'SAPMSSFO'.
<ls_bdcdata>-dynpro = '0100'.
<ls_bdcdata>-dynbegin = abap_true.
SELECT SINGLE formtype FROM stxfadm INTO lv_formtype
WHERE formname = ms_item-obj_name.
IF lv_formtype = cssf_formtype_text.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'RB_TX'.
<ls_bdcdata>-fval = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BDC_OKCODE'.
<ls_bdcdata>-fval = '=RB'.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-program = 'SAPMSSFO'.
<ls_bdcdata>-dynpro = '0100'.
<ls_bdcdata>-dynbegin = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'SSFSCREEN-TNAME'.
<ls_bdcdata>-fval = ms_item-obj_name.
ELSE.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'SSFSCREEN-FNAME'.
<ls_bdcdata>-fval = ms_item-obj_name.
ENDIF.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BDC_OKCODE'.
<ls_bdcdata>-fval = '=DISPLAY'.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SMARTFORMS'
mode_val = 'E'
TABLES
using_tab = lt_bdcdata
EXCEPTIONS
system_failure = 1
communication_failure = 2
resource_failure = 3
OTHERS = 4
##fm_subrc_ok. "#EC CI_SUBRC
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_formname TYPE tdsfname.
lv_formname = ms_item-obj_name.
CALL FUNCTION 'FB_DELETE_FORM'
EXPORTING
i_formname = lv_formname
i_with_dialog = abap_false
i_with_confirm_dialog = abap_false
EXCEPTIONS
no_name = 1
no_form = 2
form_locked = 3
no_access_permission = 4
illegal_language = 5
illegal_formtype = 6
OTHERS = 7.
IF sy-subrc <> 0 AND sy-subrc <> 2.
zcx_abapgit_exception=>raise( 'Error from FB_DELETE_FORM' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_sf TYPE REF TO cl_ssf_fb_smart_form,
lv_name TYPE string,
li_node TYPE REF TO if_ixml_node,
li_element TYPE REF TO if_ixml_element,
li_iterator TYPE REF TO if_ixml_node_iterator,
lv_formname TYPE tdsfname,
li_ixml TYPE REF TO if_ixml,
li_xml_doc TYPE REF TO if_ixml_document.
li_ixml = cl_ixml=>create( ).
li_xml_doc = li_ixml->create_document( ).
CREATE OBJECT lo_sf.
lv_formname = ms_item-obj_name. " convert type
TRY.
lo_sf->load( im_formname = lv_formname
im_language = '' ).
CATCH cx_ssf_fb.
RETURN.
ENDTRY.
lo_sf->xml_download( EXPORTING parent = li_xml_doc
CHANGING document = li_xml_doc ).
li_iterator = li_xml_doc->create_iterator( ).
li_node = li_iterator->get_next( ).
WHILE NOT li_node IS INITIAL.
lv_name = li_node->get_name( ).
IF lv_name = 'DEVCLASS'
OR lv_name = 'LASTDATE'
OR lv_name = 'LASTTIME'.
li_node->set_value( '' ).
ENDIF.
IF lv_name = 'FIRSTUSER'
OR lv_name = 'LASTUSER'.
li_node->set_value( 'DUMMY' ).
ENDIF.
li_node = li_iterator->get_next( ).
ENDWHILE.
fix_ids( li_xml_doc ).
li_element = li_xml_doc->get_root_element( ).
li_element->set_attribute(
name = 'sf'
namespace = 'xmlns'
value = 'urn:sap-com:SmartForms:2000:internal-structure' ). "#EC NOTEXT
li_element->set_attribute(
name = 'xmlns'
value = 'urn:sap-com:sdixml-ifr:2000' ). "#EC NOTEXT
io_xml->set_raw( li_xml_doc->get_root_element( ) ).
ENDMETHOD.
METHOD fix_ids.
DATA: lv_name TYPE string,
li_idref TYPE REF TO if_ixml_node,
li_node TYPE REF TO if_ixml_node,
li_attr TYPE REF TO if_ixml_named_node_map,
li_iterator TYPE REF TO if_ixml_node_iterator,
lt_idref TYPE STANDARD TABLE OF string WITH DEFAULT KEY.
li_iterator = ii_xml_doc->create_iterator( ).
li_node = li_iterator->get_next( ).
WHILE NOT li_node IS INITIAL.
lv_name = li_node->get_name( ).
IF lv_name = 'NODE' OR lv_name = 'WINDOW'.
li_idref = li_node->get_attributes( )->get_named_item( 'IDREF' ).
IF li_idref IS BOUND.
APPEND li_idref->get_value( ) TO lt_idref.
li_idref->set_value( |{ sy-tabix }| ).
ENDIF.
ENDIF.
li_node = li_iterator->get_next( ).
ENDWHILE.
li_iterator = ii_xml_doc->create_iterator( ).
li_node = li_iterator->get_next( ).
WHILE NOT li_node IS INITIAL.
lv_name = li_node->get_name( ).
IF lv_name = 'NODE' OR lv_name = 'WINDOW'.
li_idref = li_node->get_attributes( )->get_named_item( 'ID' ).
IF li_idref IS BOUND.
lv_name = li_idref->get_value( ).
READ TABLE lt_idref WITH KEY table_line = lv_name TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
li_idref->set_value( |{ sy-tabix }| ).
ELSE.
li_attr = li_node->get_attributes( ).
li_attr->remove_named_item( 'ID' ).
ENDIF.
ENDIF.
ENDIF.
li_node = li_iterator->get_next( ).
ENDWHILE.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: li_node TYPE REF TO if_ixml_node,
lv_formname TYPE tdsfname,
lv_name TYPE string,
li_iterator TYPE REF TO if_ixml_node_iterator,
lo_sf TYPE REF TO cl_ssf_fb_smart_form,
lo_res TYPE REF TO cl_ssf_fb_smart_form,
lx_error TYPE REF TO cx_ssf_fb,
lv_text TYPE string.
CREATE OBJECT lo_sf.
li_iterator = io_xml->get_raw( )->get_root_element( )->create_iterator( ).
li_node = li_iterator->get_next( ).
WHILE NOT li_node IS INITIAL.
lv_name = li_node->get_name( ).
CASE lv_name.
WHEN 'LASTDATE'.
li_node->set_value(
sy-datum(4) && '-' && sy-datum+4(2) && '-' && sy-datum+6(2) ).
WHEN 'LASTTIME'.
li_node->set_value(
sy-uzeit(2) && ':' && sy-uzeit+2(2) && ':' && sy-uzeit+4(2) ).
WHEN 'FIRSTUSER' OR 'LASTUSER'.
li_node->set_value( sy-uname && '' ).
ENDCASE.
li_node = li_iterator->get_next( ).
ENDWHILE.
tadir_insert( iv_package ).
lv_formname = ms_item-obj_name.
TRY.
lo_sf->enqueue( suppress_corr_check = space
master_language = mv_language
mode = 'INSERT'
formname = lv_formname ).
lo_sf->xml_upload( EXPORTING dom = io_xml->get_raw( )->get_root_element( )
formname = lv_formname
language = mv_language
CHANGING sform = lo_res ).
lo_res->store( im_formname = lo_res->header-formname
im_language = mv_language
im_active = abap_true ).
lo_sf->dequeue( lv_formname ).
CATCH cx_ssf_fb INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( |{ ms_item-obj_type } { ms_item-obj_name }: { lv_text } | ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'E_SMFORM'
iv_argument = |{ ms_item-obj_name }| ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_SRFC IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: li_srfc_persist TYPE REF TO if_wb_object_persist,
lx_error TYPE REF TO cx_root,
lv_text TYPE string.
TRY.
CREATE OBJECT li_srfc_persist TYPE ('CL_UCONRFC_OBJECT_PERSIST').
li_srfc_persist->delete( p_object_key = |{ ms_item-obj_name }|
p_version = 'A' ).
CATCH cx_root INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: li_srfc_persist TYPE REF TO if_wb_object_persist,
li_object_data TYPE REF TO if_wb_object_data_model,
lv_text TYPE string,
lr_srfc_data TYPE REF TO data,
lx_error TYPE REF TO cx_root.
FIELD-SYMBOLS: <lg_srfc_data> TYPE any.
TRY.
CREATE DATA lr_srfc_data TYPE ('UCONRFCSERV_COMPLETE').
ASSIGN lr_srfc_data->* TO <lg_srfc_data>.
ASSERT sy-subrc = 0.
io_xml->read(
EXPORTING
iv_name = 'SRFC'
CHANGING
cg_data = <lg_srfc_data> ).
CREATE OBJECT li_srfc_persist TYPE ('CL_UCONRFC_OBJECT_PERSIST').
CREATE OBJECT li_object_data TYPE ('CL_UCONRFC_OBJECT_DATA').
li_object_data->set_data( <lg_srfc_data> ).
li_srfc_persist->save( li_object_data ).
tadir_insert( iv_package ).
CATCH cx_root INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: li_object_data TYPE REF TO if_wb_object_data_model,
li_srfc_persist TYPE REF TO if_wb_object_persist.
TRY.
CREATE OBJECT li_srfc_persist TYPE ('CL_UCONRFC_OBJECT_PERSIST').
li_srfc_persist->get(
EXPORTING
p_object_key = |{ ms_item-obj_name }|
p_version = 'A'
CHANGING
p_object_data = li_object_data ).
CATCH cx_root.
rv_bool = abap_false.
RETURN.
ENDTRY.
rv_bool = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name " Object Name
object_type = ms_item-obj_type " Object Type
in_new_window = abap_true
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_TOOL_ACCESS' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: li_object_data TYPE REF TO if_wb_object_data_model,
li_srfc_persist TYPE REF TO if_wb_object_persist,
lr_srfc_data TYPE REF TO data,
lx_error TYPE REF TO cx_root,
lv_text TYPE string.
FIELD-SYMBOLS: <lg_srfc_data> TYPE any.
TRY.
CREATE DATA lr_srfc_data TYPE ('UCONRFCSERV_COMPLETE').
ASSIGN lr_srfc_data->* TO <lg_srfc_data>.
ASSERT sy-subrc = 0.
CREATE OBJECT li_srfc_persist TYPE ('CL_UCONRFC_OBJECT_PERSIST').
li_srfc_persist->get(
EXPORTING
p_object_key = |{ ms_item-obj_name }|
p_version = 'A'
CHANGING
p_object_data = li_object_data ).
li_object_data->get_data(
IMPORTING
p_data = <lg_srfc_data> ).
CATCH cx_root INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
io_xml->add( iv_name = 'SRFC'
ig_data = <lg_srfc_data> ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_splo IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE chgname1 FROM tsp1d INTO rv_user
WHERE papart = ms_item-obj_name.
IF sy-subrc <> 0 OR rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_tsp1t TYPE tsp1t,
ls_tsp1d TYPE tsp1d,
ls_tsp0p TYPE tsp0p.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
SELECT SINGLE * FROM tsp1t INTO ls_tsp1t
WHERE papart = ms_item-obj_name
AND spras = mv_language. "#EC CI_GENBUFF "#EC CI_SUBRC
SELECT SINGLE * FROM tsp1d INTO ls_tsp1d
WHERE papart = ms_item-obj_name. "#EC CI_SUBRC
SELECT SINGLE * FROM tsp0p INTO ls_tsp0p
WHERE pdpaper = ms_item-obj_name. "#EC CI_SUBRC
CLEAR: ls_tsp1d-chgname1,
ls_tsp1d-chgtstmp1,
ls_tsp1d-chgsaprel1,
ls_tsp1d-chgsapsys1.
io_xml->add( iv_name = 'TSPLT'
ig_data = ls_tsp1t ).
io_xml->add( iv_name = 'TSPLD'
ig_data = ls_tsp1d ).
io_xml->add( iv_name = 'TSP0P'
ig_data = ls_tsp0p ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_tsp1t TYPE tsp1t,
ls_tsp1d TYPE tsp1d,
ls_tsp0p TYPE tsp0p.
io_xml->read( EXPORTING iv_name = 'TSPLT'
CHANGING cg_data = ls_tsp1t ).
io_xml->read( EXPORTING iv_name = 'TSPLD'
CHANGING cg_data = ls_tsp1d ).
io_xml->read( EXPORTING iv_name = 'TSP0P'
CHANGING cg_data = ls_tsp0p ).
MODIFY tsp1t FROM ls_tsp1t. "#EC CI_SUBRC
MODIFY tsp1d FROM ls_tsp1d. "#EC CI_SUBRC
MODIFY tsp0p FROM ls_tsp0p. "#EC CI_SUBRC
tadir_insert( iv_package ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DELETE FROM tsp1t WHERE papart = ms_item-obj_name. "#EC CI_NOFIRST "#EC CI_SUBRC
DELETE FROM tsp1d WHERE papart = ms_item-obj_name. "#EC CI_SUBRC
DELETE FROM tsp0p WHERE pdpaper = ms_item-obj_name. "#EC CI_SUBRC
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_papart TYPE tsp1d-papart.
SELECT SINGLE papart INTO lv_papart FROM tsp1d
WHERE papart = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( 'todo, jump, SPLO' ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_smim IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lv_loio TYPE sdok_docid.
lv_loio = ms_item-obj_name.
SELECT SINGLE chng_user FROM smimloio INTO rv_user
WHERE loio_id = lv_loio. "#EC CI_GENBUFF
IF sy-subrc <> 0 OR rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_loio TYPE sdok_docid.
lv_loio = ms_item-obj_name.
SELECT SINGLE loio_id FROM smimloio INTO lv_loio
WHERE loio_id = lv_loio. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD get_url_for_io.
DATA: ls_io TYPE skwf_io,
lv_url TYPE skwf_url,
ls_smimloio TYPE smimloio,
lv_loio TYPE sdok_docid.
lv_loio = ms_item-obj_name.
CLEAR ev_url.
CLEAR ev_is_folder.
SELECT SINGLE * FROM smimloio INTO ls_smimloio
WHERE loio_id = lv_loio. "#EC CI_GENBUFF
IF sy-subrc <> 0.
RAISE EXCEPTION TYPE zcx_abapgit_not_found.
ENDIF.
IF ls_smimloio-lo_class = wbmr_c_skwf_folder_class.
ev_is_folder = abap_true.
ls_io-objtype = skwfc_obtype_folder.
ELSE.
ls_io-objtype = skwfc_obtype_loio.
ENDIF.
ls_io-class = ls_smimloio-lo_class.
ls_io-objid = ls_smimloio-loio_id.
CALL FUNCTION 'SKWF_NMSPC_IO_ADDRESS_GET'
EXPORTING
io = ls_io
IMPORTING
url = lv_url.
ev_url = lv_url.
ENDMETHOD.
METHOD build_filename.
CONCATENATE ms_item-obj_name ms_item-obj_type iv_filename
INTO rv_filename SEPARATED BY '.'.
TRANSLATE rv_filename TO LOWER CASE.
ENDMETHOD.
METHOD find_content.
DATA: lv_filename TYPE string,
lt_files TYPE zif_abapgit_definitions=>ty_files_tt.
FIELD-SYMBOLS: <ls_file> LIKE LINE OF lt_files.
lv_filename = get_filename( iv_url ).
lv_filename = build_filename( lv_filename ).
lt_files = mo_files->get_files( ).
READ TABLE lt_files ASSIGNING <ls_file> WITH KEY filename = lv_filename.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'SMIM, file not found' ).
ENDIF.
rv_content = <ls_file>-data.
ENDMETHOD.
METHOD get_filename.
DATA: lv_lines TYPE i,
lt_strings TYPE TABLE OF string.
SPLIT iv_url AT '/' INTO TABLE lt_strings.
lv_lines = lines( lt_strings ).
ASSERT lv_lines > 0.
READ TABLE lt_strings INDEX lv_lines INTO rv_filename.
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_url TYPE string,
lv_folder TYPE abap_bool,
lv_filename TYPE string,
lv_class TYPE smimloio-lo_class,
ls_file TYPE zif_abapgit_definitions=>ty_file,
lv_content TYPE xstring,
li_api TYPE REF TO if_mr_api,
lv_loio TYPE sdok_docid.
lv_loio = ms_item-obj_name.
TRY.
get_url_for_io(
IMPORTING
ev_url = lv_url
ev_is_folder = lv_folder ).
CATCH zcx_abapgit_not_found.
RETURN.
ENDTRY.
IF lv_folder = abap_false.
li_api = cl_mime_repository_api=>if_mr_api~get_api( ).
li_api->get(
EXPORTING
i_url = lv_url
IMPORTING
e_content = lv_content
EXCEPTIONS
parameter_missing = 1
error_occured = 2
not_found = 3
permission_failure = 4
OTHERS = 5 ).
IF sy-subrc <> 0 AND sy-subrc <> 2 AND sy-subrc <> 3.
zcx_abapgit_exception=>raise( 'error from mime api->get:' && sy-msgv1 ).
ENDIF.
lv_filename = get_filename( lv_url ).
CLEAR ls_file.
ls_file-filename = build_filename( lv_filename ).
ls_file-path = '/'.
ls_file-data = lv_content.
mo_files->add( ls_file ).
SELECT SINGLE lo_class FROM smimloio INTO lv_class
WHERE loio_id = lv_loio. "#EC CI_GENBUFF
ENDIF.
io_xml->add( iv_name = 'URL'
ig_data = lv_url ).
io_xml->add( iv_name = 'FOLDER'
ig_data = lv_folder ).
io_xml->add( iv_name = 'CLASS'
ig_data = lv_class ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_url TYPE string,
lv_folder TYPE abap_bool,
lv_content TYPE xstring,
lv_filename TYPE skwf_filnm,
lv_io TYPE sdok_docid,
lv_class TYPE smimloio-lo_class,
ls_skwf_io TYPE skwf_io,
li_api TYPE REF TO if_mr_api.
li_api = cl_mime_repository_api=>if_mr_api~get_api( ).
lv_io = ms_item-obj_name.
io_xml->read( EXPORTING iv_name = 'URL'
CHANGING cg_data = lv_url ).
io_xml->read( EXPORTING iv_name = 'FOLDER'
CHANGING cg_data = lv_folder ).
io_xml->read( EXPORTING iv_name = 'CLASS'
CHANGING cg_data = lv_class ).
ls_skwf_io-objid = lv_io.
IF lv_folder = abap_true.
li_api->create_folder(
EXPORTING
i_url = lv_url
i_language = sy-langu
i_dev_package = iv_package
i_folder_loio = ls_skwf_io
EXCEPTIONS
parameter_missing = 1
error_occured = 2
cancelled = 3
permission_failure = 4
folder_exists = 5
OTHERS = 6 ).
IF sy-subrc <> 5 AND sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error frrom SMIM create_folder' ).
ENDIF.
ELSE.
lv_filename = get_filename( lv_url ).
ls_skwf_io-class = lv_class.
IF ls_skwf_io-class IS INITIAL.
cl_wb_mime_repository=>determine_io_class(
EXPORTING
filename = lv_filename
IMPORTING
io_class = ls_skwf_io-class ).
CONCATENATE ls_skwf_io-class '_L' INTO ls_skwf_io-class.
ENDIF.
lv_content = find_content( lv_url ).
li_api->put(
EXPORTING
i_url = lv_url
i_content = lv_content
i_dev_package = iv_package
i_new_loio = ls_skwf_io
EXCEPTIONS
parameter_missing = 1
error_occured = 2
cancelled = 3
permission_failure = 4
data_inconsistency = 5
new_loio_already_exists = 6
is_folder = 7
OTHERS = 8 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SMIM put' ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: li_api TYPE REF TO if_mr_api,
lv_url TYPE string.
TRY.
get_url_for_io(
IMPORTING
ev_url = lv_url ).
CATCH zcx_abapgit_not_found.
RETURN.
ENDTRY.
li_api = cl_mime_repository_api=>if_mr_api~get_api( ).
li_api->delete(
EXPORTING
i_url = lv_url
i_delete_children = abap_true
EXCEPTIONS
parameter_missing = 1
error_occured = 2
cancelled = 3
permission_failure = 4
not_found = 5
OTHERS = 6 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from delete' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_SICF IMPLEMENTATION.
METHOD change_sicf.
DATA: lt_icfhndlist TYPE icfhndlist,
lt_existing TYPE TABLE OF icfhandler,
ls_icfserdesc TYPE icfserdesc.
FIELD-SYMBOLS: <ls_existing> LIKE LINE OF lt_existing.
lt_icfhndlist = to_icfhndlist( it_icfhandler ).
SELECT * FROM icfhandler INTO TABLE lt_existing
WHERE icf_name = is_icfservice-icf_name.
LOOP AT lt_existing ASSIGNING <ls_existing>.
DELETE TABLE lt_icfhndlist FROM <ls_existing>-icfhandler.
ENDLOOP.
MOVE-CORRESPONDING is_icfservice TO ls_icfserdesc.
cl_icf_tree=>if_icf_tree~change_node(
EXPORTING
icf_name = is_icfservice-orig_name
icfparguid = iv_parent
icfdocu = is_icfdocu
doculang = mv_language
icfhandlst = lt_icfhndlist
package = iv_package
application = space
icfserdesc = ls_icfserdesc
icfactive = abap_true
EXCEPTIONS
empty_icf_name = 1
no_new_virtual_host = 2
special_service_error = 3
parent_not_existing = 4
enqueue_error = 5
node_already_existing = 6
empty_docu = 7
doculang_not_installed = 8
security_info_error = 9
user_password_error = 10
password_encryption_error = 11
invalid_url = 12
invalid_otr_concept = 13
formflg401_error = 14
handler_error = 15
transport_error = 16
tadir_error = 17
package_not_found = 18
wrong_application = 19
not_allow_application = 20
no_application = 21
invalid_icfparguid = 22
alt_name_invalid = 23
alternate_name_exist = 24
wrong_icf_name = 25
no_authority = 26
OTHERS = 27 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'SICF - error from change_node' ).
ENDIF.
ENDMETHOD.
METHOD find_parent.
cl_icf_tree=>if_icf_tree~service_from_url(
EXPORTING
url = iv_url
hostnumber = 0
IMPORTING
icfnodguid = rv_parent
EXCEPTIONS
wrong_application = 1
no_application = 2
not_allow_application = 3
wrong_url = 4
no_authority = 5
OTHERS = 6 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'SICF - error from service_from_url' ).
ENDIF.
ENDMETHOD.
METHOD insert_sicf.
DATA: lt_icfhndlist TYPE icfhndlist,
ls_icfserdesc TYPE icfserdesc,
ls_icfdocu TYPE icfdocu,
lv_parent TYPE icfparguid.
lt_icfhndlist = to_icfhndlist( it_icfhandler ).
lv_parent = find_parent( iv_url ).
ls_icfdocu = is_icfdocu-icf_docu.
MOVE-CORRESPONDING is_icfservice TO ls_icfserdesc.
cl_icf_tree=>if_icf_tree~insert_node(
EXPORTING
icf_name = is_icfservice-orig_name
icfparguid = lv_parent
icfdocu = ls_icfdocu
doculang = mv_language
icfhandlst = lt_icfhndlist
package = iv_package
application = space
icfserdesc = ls_icfserdesc
icfactive = abap_true
EXCEPTIONS
empty_icf_name = 1
no_new_virtual_host = 2
special_service_error = 3
parent_not_existing = 4
enqueue_error = 5
node_already_existing = 6
empty_docu = 7
doculang_not_installed = 8
security_info_error = 9
user_password_error = 10
password_encryption_error = 11
invalid_url = 12
invalid_otr_concept = 13
formflg401_error = 14
handler_error = 15
transport_error = 16
tadir_error = 17
package_not_found = 18
wrong_application = 19
not_allow_application = 20
no_application = 21
invalid_icfparguid = 22
alt_name_invalid = 23
alternate_name_exist = 24
wrong_icf_name = 25
no_authority = 26
OTHERS = 27 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |SICF - error from insert_node: { sy-subrc }| ).
ENDIF.
ENDMETHOD.
METHOD read.
DATA: lt_serv_info TYPE icfservtbl,
ls_serv_info LIKE LINE OF lt_serv_info,
ls_key TYPE ty_sicf_key.
FIELD-SYMBOLS: <ls_icfhandler> LIKE LINE OF et_icfhandler.
CLEAR es_icfservice.
CLEAR es_icfdocu.
CLEAR et_icfhandler.
CLEAR ev_url.
ls_key = read_tadir_sicf( ms_item-obj_name )-obj_name.
cl_icf_tree=>if_icf_tree~get_info_from_serv(
EXPORTING
icf_name = ls_key-icf_name
icfparguid = ls_key-icfparguid
icf_langu = mv_language
IMPORTING
serv_info = lt_serv_info
icfdocu = es_icfdocu
url = ev_url
EXCEPTIONS
wrong_name = 1
wrong_parguid = 2
incorrect_service = 3
no_authority = 4
OTHERS = 5 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'SICF - error from get_info_from_serv' ).
ENDIF.
ASSERT lines( lt_serv_info ) = 1.
READ TABLE lt_serv_info INDEX 1 INTO ls_serv_info.
ASSERT sy-subrc = 0.
MOVE-CORRESPONDING ls_serv_info-service TO es_icfservice.
IF iv_clear = abap_true.
CLEAR es_icfservice-icf_cuser.
CLEAR es_icfservice-icf_cdate.
CLEAR es_icfservice-icf_muser.
CLEAR es_icfservice-icf_mdate.
ENDIF.
CLEAR es_icfdocu-icfparguid.
APPEND LINES OF ls_serv_info-handlertbl TO et_icfhandler.
LOOP AT et_icfhandler ASSIGNING <ls_icfhandler>.
CLEAR <ls_icfhandler>-icfparguid.
ENDLOOP.
ENDMETHOD.
METHOD read_sicf_url.
DATA: lv_name TYPE icfname,
lv_url TYPE string,
lv_parguid TYPE icfparguid.
lv_name = iv_obj_name.
lv_parguid = iv_obj_name+15.
cl_icf_tree=>if_icf_tree~get_info_from_serv(
EXPORTING
icf_name = lv_name
icfparguid = lv_parguid
IMPORTING
url = lv_url
EXCEPTIONS
wrong_name = 1
wrong_parguid = 2
incorrect_service = 3
no_authority = 4
OTHERS = 5 ).
IF sy-subrc = 0.
rv_hash = zcl_abapgit_hash=>sha1_raw( zcl_abapgit_convert=>string_to_xstring_utf8( lv_url ) ).
ENDIF.
ENDMETHOD.
METHOD read_tadir_sicf.
DATA: lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt,
lv_hash TYPE text25,
lv_obj_name TYPE tadir-obj_name.
FIELD-SYMBOLS: <ls_tadir> LIKE LINE OF lt_tadir.
lv_hash = iv_obj_name+15.
CONCATENATE iv_obj_name(15) '%' INTO lv_obj_name.
SELECT * FROM tadir INTO CORRESPONDING FIELDS OF TABLE lt_tadir
WHERE pgmid = iv_pgmid
AND object = 'SICF'
AND obj_name LIKE lv_obj_name
ORDER BY PRIMARY KEY. "#EC CI_GENBUFF
LOOP AT lt_tadir ASSIGNING <ls_tadir>.
IF read_sicf_url( <ls_tadir>-obj_name ) = lv_hash.
rs_tadir = <ls_tadir>.
RETURN.
ENDIF.
ENDLOOP.
IF lines( lt_tadir ) = 1.
READ TABLE lt_tadir INDEX 1 ASSIGNING <ls_tadir>.
ASSERT sy-subrc = 0.
rs_tadir = <ls_tadir>.
ENDIF.
ENDMETHOD.
METHOD to_icfhndlist.
FIELD-SYMBOLS: <ls_list> LIKE LINE OF it_list.
LOOP AT it_list ASSIGNING <ls_list>.
INSERT <ls_list>-icfhandler INTO TABLE rt_list.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_icfservice TYPE icfservice.
read( EXPORTING iv_clear = abap_false
IMPORTING es_icfservice = ls_icfservice ).
rv_user = ls_icfservice-icf_muser.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_icfservice TYPE icfservice.
read( IMPORTING es_icfservice = ls_icfservice ).
IF ls_icfservice IS INITIAL.
" It seems that the ICF service doesn't exist anymore.
" But that's ok, because some objects like SAPC manage
" the lifecycle of its ICF service by itself and already
" deleted the service.
RETURN.
ENDIF.
IF ls_icfservice-icfparguid CO '0'.
" not supported by the SAP standard API
zcx_abapgit_exception=>raise( 'SICF - cannot delete root node, delete node manually' ).
ENDIF.
" Delete Application Customizing Data the hard way, as it isn't done by the API.
" If we wouldn't we would get errors from the API if entrys exist.
" Transaction SICF does the same.
DELETE FROM icfapplcust
WHERE icf_name = ls_icfservice-icf_name
AND icfparguid = ls_icfservice-icfparguid.
cl_icf_tree=>if_icf_tree~delete_node(
EXPORTING
icfparguid = ls_icfservice-icfparguid
CHANGING
icf_name = ls_icfservice-icf_name
EXCEPTIONS
no_virtual_host_delete = 1
special_service_error = 2
enqueue_error = 3
node_not_existing = 4
node_has_childs = 5
node_is_aliased = 6
node_not_in_original_system = 7
transport_error = 8
tadir_error = 9
db_error = 10
no_authority = 11
OTHERS = 12 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'SICF - error from delete_node' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_icfservice TYPE icfservice,
ls_read TYPE icfservice,
ls_icfdocu TYPE icfdocu,
lv_url TYPE string,
lv_exists TYPE abap_bool,
lt_icfhandler TYPE TABLE OF icfhandler.
io_xml->read( EXPORTING iv_name = 'URL'
CHANGING cg_data = lv_url ).
io_xml->read( EXPORTING iv_name = 'ICFSERVICE'
CHANGING cg_data = ls_icfservice ).
io_xml->read( EXPORTING iv_name = 'ICFDOCU'
CHANGING cg_data = ls_icfdocu ).
io_xml->read( EXPORTING iv_name = 'ICFHANDLER_TABLE'
CHANGING cg_data = lt_icfhandler ).
lv_exists = zif_abapgit_object~exists( ).
IF lv_exists = abap_false.
insert_sicf( is_icfservice = ls_icfservice
is_icfdocu = ls_icfdocu
it_icfhandler = lt_icfhandler
iv_package = iv_package
iv_url = lv_url ).
ELSE.
read( IMPORTING es_icfservice = ls_read ).
change_sicf( is_icfservice = ls_icfservice
is_icfdocu = ls_icfdocu
it_icfhandler = lt_icfhandler
iv_package = iv_package
iv_parent = ls_read-icfparguid ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_tadir TYPE zif_abapgit_definitions=>ty_tadir,
ls_key TYPE ty_sicf_key.
ls_tadir = read_tadir_sicf( ms_item-obj_name ).
rv_bool = boolc( NOT ls_tadir IS INITIAL ).
IF rv_bool = abap_true.
ls_key = ls_tadir-obj_name.
SELECT SINGLE icfaltnme FROM icfservice INTO ls_key-icf_name
WHERE icf_name = ls_key-icf_name
AND icfparguid = ls_key-icfparguid.
rv_bool = boolc( sy-subrc = 0 ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
ls_bcdata-program = 'RSICFTREE'.
ls_bcdata-dynpro = '1000'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
ls_bcdata-dynpro = space.
ls_bcdata-dynbegin = space.
ls_bcdata-fnam = 'ICF_SERV'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=ONLI'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SICF'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SICF' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_icfservice TYPE icfservice,
ls_icfdocu TYPE icfdocu,
lv_url TYPE string,
lt_icfhandler TYPE TABLE OF icfhandler.
read( IMPORTING es_icfservice = ls_icfservice
es_icfdocu = ls_icfdocu
et_icfhandler = lt_icfhandler
ev_url = lv_url ).
IF ls_icfservice IS INITIAL.
RETURN.
ENDIF.
CLEAR ls_icfservice-icf_mandt.
CLEAR ls_icfservice-icfnodguid.
CLEAR ls_icfservice-icfparguid.
CLEAR ls_icfservice-icf_user.
CLEAR ls_icfservice-icf_cclnt.
CLEAR ls_icfservice-icf_mclnt.
io_xml->add( iv_name = 'URL'
ig_data = lv_url ).
io_xml->add( iv_name = 'ICFSERVICE'
ig_data = ls_icfservice ).
io_xml->add( iv_name = 'ICFDOCU'
ig_data = ls_icfdocu ).
io_xml->add( iv_name = 'ICFHANDLER_TABLE'
ig_data = lt_icfhandler ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_shma IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_area_name TYPE shm_area_name.
SELECT SINGLE area_name
FROM shma_attributes
INTO lv_area_name
WHERE area_name = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_area_name TYPE shm_area_name,
ls_area_attributes TYPE shma_attributes.
lv_area_name = ms_item-obj_name.
TRY.
CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('READ_AREA_ATTRIBUTES_ALL')
EXPORTING
area_name = lv_area_name
IMPORTING
area_attributes = ls_area_attributes.
CLEAR: ls_area_attributes-chg_user,
ls_area_attributes-chg_date,
ls_area_attributes-chg_time,
ls_area_attributes-cls_gen_user,
ls_area_attributes-cls_gen_date,
ls_area_attributes-cls_gen_time.
io_xml->add( iv_name = 'AREA_ATTRIBUTES'
ig_data = ls_area_attributes ).
CATCH cx_root.
zcx_abapgit_exception=>raise( |Error serializing SHMA { ms_item-obj_name }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_area_name TYPE shm_area_name,
ls_area_attributes TYPE shma_attributes.
lv_area_name = ms_item-obj_name.
io_xml->read(
EXPORTING
iv_name = 'AREA_ATTRIBUTES'
CHANGING
cg_data = ls_area_attributes ).
TRY.
CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('INSERT_AREA')
EXPORTING
area_name = lv_area_name
attributes = ls_area_attributes
force_overwrite = abap_true
no_class_generation = abap_true
silent_mode = abap_true.
CATCH cx_root.
zcx_abapgit_exception=>raise( |Error serializing SHMA { ms_item-obj_name }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
" We can't use FM SHMA_DELETE_AREA because it depends
" on the corresponding class, but in abapGit it has its own
" lifecycle. Therefore we have to reimplement most of the
" FMs logic
CONSTANTS: lc_request_delete TYPE i VALUE 4.
DATA: lv_request TYPE i,
lv_area_name TYPE shm_area_name,
lv_order TYPE e070-trkorr,
lv_korrnum TYPE tadir-korrnum,
lv_objname TYPE tadir-obj_name,
lv_task TYPE e070-trkorr,
lv_append TYPE abap_bool,
ls_tadir TYPE tadir,
ls_tdevc TYPE tdevc,
lo_cts_if TYPE REF TO object.
lv_area_name = ms_item-obj_name.
TRY.
CALL FUNCTION 'ENQUEUE_E_SHM_AREA'
EXPORTING
mode_shma_attributes = 'E'
area_name = lv_area_name
x_area_name = ' '
_scope = '2'
_wait = ' '
_collect = ' '
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
ENDIF.
CALL METHOD ('\PROGRAM=SAPMSHM_MONITOR\CLASS=LCL_SHMM')=>('FREE_AREA_BY_NAME')
EXPORTING
area_name = lv_area_name
affect_server = cl_shm_area=>affect_all_servers.
CREATE OBJECT lo_cts_if TYPE ('\FUNCTION-POOL=SHMA\CLASS=LCL_CTS_INTERFACE')
EXPORTING
area = lv_area_name.
CALL METHOD lo_cts_if->('CHECK_AREA')
EXPORTING
request = lc_request_delete
IMPORTING
access_mode = lv_request
appendable = lv_append.
IF lv_request <> lc_request_delete.
zcx_abapgit_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
ENDIF.
CALL METHOD lo_cts_if->('INSERT_AREA')
EXPORTING
request = lc_request_delete
IMPORTING
order = lv_order
task = lv_task.
DELETE FROM shma_attributes WHERE area_name = lv_area_name.
DELETE FROM shma_start WHERE area_name = lv_area_name.
lv_korrnum = lv_order.
lv_objname = lv_area_name.
CALL FUNCTION 'TR_TADIR_INTERFACE'
EXPORTING
wi_read_only = abap_true
wi_tadir_pgmid = 'R3TR'
wi_tadir_object = 'SHMA'
wi_tadir_obj_name = lv_objname
IMPORTING
new_tadir_entry = ls_tadir
EXCEPTIONS
OTHERS = 0.
CALL FUNCTION 'TR_DEVCLASS_GET'
EXPORTING
iv_devclass = ls_tadir-devclass
IMPORTING
es_tdevc = ls_tdevc
EXCEPTIONS
OTHERS = 1.
IF sy-subrc = 0 AND ls_tdevc-korrflag IS INITIAL.
" TADIR entries for local objects must be deleted 'by hand'
CALL FUNCTION 'TR_TADIR_INTERFACE'
EXPORTING
wi_test_modus = abap_false
wi_delete_tadir_entry = abap_true
wi_tadir_pgmid = 'R3TR'
wi_tadir_object = 'SHMA'
wi_tadir_obj_name = lv_objname
wi_tadir_korrnum = lv_korrnum
EXCEPTIONS
OTHERS = 0.
ENDIF.
CALL METHOD ('\PROGRAM=SAPLSHMA\CLASS=LCL_SHMA_HELPER')=>('DELETE_RUNTIME_SETTINGS')
EXPORTING
area_name = lv_area_name.
CALL FUNCTION 'DEQUEUE_E_SHM_AREA'
EXPORTING
mode_shma_attributes = 'E'
area_name = lv_area_name
x_area_name = ' '
_scope = '3'
_synchron = ' '
_collect = ' '.
CATCH cx_root.
zcx_abapgit_exception=>raise( |Error deleting SHMA { ms_item-obj_name }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
ls_bcdata-program = 'SAPLSHMA'.
ls_bcdata-dynpro = '0100'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'SHMA_ATTRIBUTES-AREA_NAME'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=SHOW'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SHMA'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SHMA' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_shlp IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
DATA: lv_date TYPE dats,
lv_time TYPE tims.
SELECT SINGLE as4date as4time FROM dd30l
INTO (lv_date, lv_time)
WHERE shlpname = ms_item-obj_name
AND as4local = 'A'. "#EC CI_GENBUFF
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE as4user FROM dd30l INTO rv_user
WHERE shlpname = ms_item-obj_name
AND as4local = 'A'. "#EC CI_GENBUFF
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_shlpname TYPE dd30l-shlpname.
SELECT SINGLE shlpname FROM dd30l INTO lv_shlpname
WHERE shlpname = ms_item-obj_name
AND as4local = 'A'. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
jump_se11( iv_radio = 'RSRD1-SHMA'
iv_field = 'RSRD1-SHMA_VAL' ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objname TYPE rsedd0-ddobjname.
lv_objname = ms_item-obj_name.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = abap_true
objname = lv_objname
objtype = 'H'
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, SHLP' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_name TYPE ddobjname,
ls_dd30v TYPE dd30v,
lt_dd31v TYPE TABLE OF dd31v,
lt_dd32p TYPE TABLE OF dd32p,
lt_dd33v TYPE TABLE OF dd33v.
FIELD-SYMBOLS: <ls_dd32p> LIKE LINE OF lt_dd32p.
lv_name = ms_item-obj_name.
CALL FUNCTION 'DDIF_SHLP_GET'
EXPORTING
name = lv_name
state = 'A'
langu = mv_language
IMPORTING
dd30v_wa = ls_dd30v
TABLES
dd31v_tab = lt_dd31v
dd32p_tab = lt_dd32p
dd33v_tab = lt_dd33v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_SHLP_GET' ).
ENDIF.
IF ls_dd30v IS INITIAL.
RETURN. " does not exist in system
ENDIF.
CLEAR: ls_dd30v-as4user,
ls_dd30v-as4date,
ls_dd30v-as4time.
LOOP AT lt_dd32p ASSIGNING <ls_dd32p>.
CLEAR: <ls_dd32p>-domname,
<ls_dd32p>-headlen,
<ls_dd32p>-scrlen1,
<ls_dd32p>-scrlen2,
<ls_dd32p>-datatype,
<ls_dd32p>-leng,
<ls_dd32p>-outputlen,
<ls_dd32p>-decimals,
<ls_dd32p>-lowercase,
<ls_dd32p>-signflag,
<ls_dd32p>-convexit.
ENDLOOP.
io_xml->add( iv_name = 'DD30V'
ig_data = ls_dd30v ).
io_xml->add( ig_data = lt_dd31v
iv_name = 'DD31V_TABLE' ).
io_xml->add( ig_data = lt_dd32p
iv_name = 'DD32P_TABLE' ).
io_xml->add( ig_data = lt_dd33v
iv_name = 'DD33V_TABLE' ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_name TYPE ddobjname,
ls_dd30v TYPE dd30v,
lt_dd31v TYPE TABLE OF dd31v,
lt_dd32p TYPE TABLE OF dd32p,
lt_dd33v TYPE TABLE OF dd33v.
io_xml->read( EXPORTING iv_name = 'DD30V'
CHANGING cg_data = ls_dd30v ).
io_xml->read( EXPORTING iv_name = 'DD31V_TABLE'
CHANGING cg_data = lt_dd31v ).
io_xml->read( EXPORTING iv_name = 'DD32P_TABLE'
CHANGING cg_data = lt_dd32p ).
io_xml->read( EXPORTING iv_name = 'DD33V_TABLE'
CHANGING cg_data = lt_dd33v ).
corr_insert( iv_package ).
lv_name = ms_item-obj_name.
CALL FUNCTION 'DDIF_SHLP_PUT'
EXPORTING
name = lv_name
dd30v_wa = ls_dd30v
TABLES
dd31v_tab = lt_dd31v
dd32p_tab = lt_dd32p
dd33v_tab = lt_dd33v
EXCEPTIONS
shlp_not_found = 1
name_inconsistent = 2
shlp_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_SHLP_PUT' ).
ENDIF.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_shi8 IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_assignment_id = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( |TODO: Jump SHI8| ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
CALL FUNCTION 'STREE_SFW_ASSIGNMENT_ID_EXISTS'
EXPORTING
assignment_id = mv_assignment_id
IMPORTING
exists = rv_bool.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_deleted TYPE xfeld,
ls_message TYPE hier_mess.
CALL FUNCTION 'STREE_SFW_ASSIGNMENT_DELETE'
EXPORTING
assignment_id = mv_assignment_id
IMPORTING
id_deleted = lv_deleted
message = ls_message.
IF lv_deleted = abap_false.
zcx_abapgit_exception=>raise( |{ ls_message-msgtxt }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lt_assignments TYPE STANDARD TABLE OF hier_sfw_assignment_id,
ls_assignment LIKE LINE OF lt_assignments,
lt_assignment_data TYPE STANDARD TABLE OF ttree_sfw_nodes,
ls_assignment_data LIKE LINE OF lt_assignment_data.
ls_assignment-sfw_ass_id = mv_assignment_id.
INSERT ls_assignment INTO TABLE lt_assignments.
CALL FUNCTION 'STREE_SFW_ASSIGNMENT_READ'
TABLES
it_assignments = lt_assignments
et_assignment_data = lt_assignment_data.
READ TABLE lt_assignment_data INTO ls_assignment_data
INDEX 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error serializing { ms_item-obj_type } { ms_item-obj_name }| ).
ENDIF.
io_xml->add( iv_name = 'SHI8'
ig_data = ls_assignment_data ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_assignment_data TYPE ttree_sfw_nodes,
ls_node_data TYPE hier_iface,
lv_saved TYPE xfeld,
ls_message TYPE hier_mess.
io_xml->read(
EXPORTING
iv_name = 'SHI8'
CHANGING
cg_data = ls_assignment_data ).
ls_node_data-tree_id = ls_assignment_data-tree_id.
ls_node_data-node_id = ls_assignment_data-node_id.
CALL FUNCTION 'STREE_SFW_ASSIGNMENT_SAVE'
EXPORTING
assignment_id = ls_assignment_data-sfw_ass_id
switch_id = ls_assignment_data-switch_id
reaction = ls_assignment_data-reaction
node_data = ls_node_data
IMPORTING
data_saved = lv_saved
message = ls_message.
IF lv_saved = abap_false.
zcx_abapgit_exception=>raise( |{ ls_message-msgtxt }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_shi5 IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_extension = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( |TODO: Jump { ms_item-obj_type }| ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_extension_header TYPE ttree_ext.
CALL FUNCTION 'STREE_EXTENSION_EXISTS'
EXPORTING
extension = mv_extension
IMPORTING
extension_header = ls_extension_header.
rv_bool = boolc( ls_extension_header IS NOT INITIAL ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_message TYPE hier_mess,
lv_deletion_successful TYPE hier_yesno.
CALL FUNCTION 'STREE_EXTENSION_DELETE'
EXPORTING
extension = mv_extension
IMPORTING
message = ls_message
deletion_successful = lv_deletion_successful.
IF lv_deletion_successful = abap_false.
zcx_abapgit_exception=>raise( ls_message-msgtxt ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_extension TYPE ty_extension.
CALL FUNCTION 'STREE_EXTENSION_EXISTS'
EXPORTING
extension = mv_extension
IMPORTING
extension_header = ls_extension-header.
SELECT * FROM ttree_extt
INTO TABLE ls_extension-texts
WHERE extension = mv_extension.
io_xml->add( iv_name = 'SHI5'
ig_data = ls_extension ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
" We cannot use STREE_EXTENSION_NAME_CREATE
" the create logic is directly tied to the UI
"
" Do it like here LSHI20F01 -> SAVE_DATA
DATA: ls_extension TYPE ty_extension.
io_xml->read(
EXPORTING
iv_name = 'SHI5'
CHANGING
cg_data = ls_extension ).
INSERT ttree_ext FROM ls_extension-header.
MODIFY ttree_extt FROM TABLE ls_extension-texts.
tadir_insert( iv_package ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_shi3 IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_head TYPE ttree.
CALL FUNCTION 'STREE_STRUCTURE_READ'
EXPORTING
structure_id = mv_tree_id
IMPORTING
structure_header = ls_head.
rv_user = ls_head-luser.
ENDMETHOD.
METHOD constructor.
super->constructor( is_item = is_item iv_language = iv_language ).
mv_tree_id = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD jump_se43.
DATA: lt_bdcdata TYPE TABLE OF bdcdata.
FIELD-SYMBOLS: <ls_bdcdata> LIKE LINE OF lt_bdcdata.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-program = 'SAPLBMEN'.
<ls_bdcdata>-dynpro = '0200'.
<ls_bdcdata>-dynbegin = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BDC_OKCODE'.
<ls_bdcdata>-fval = '=SHOW'.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BMENUNAME-ID'.
<ls_bdcdata>-fval = ms_item-obj_name.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SE43'
mode_val = 'E'
TABLES
using_tab = lt_bdcdata
EXCEPTIONS
system_failure = 1
communication_failure = 2
resource_failure = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SHI3' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_head TYPE ttree.
CALL FUNCTION 'STREE_STRUCTURE_READ'
EXPORTING
structure_id = mv_tree_id
IMPORTING
structure_header = ls_head.
CASE ls_head-type.
WHEN 'BMENU'.
jump_se43( ).
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Jump for type { ls_head-type } not implemented| ).
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_msg TYPE hier_mess,
ls_header TYPE ttree,
ls_tadir TYPE tadir.
CALL FUNCTION 'STREE_STRUCTURE_EXIST'
EXPORTING
structure_id = mv_tree_id
do_not_read_devclass = ''
IMPORTING
message = ls_msg
structure_header = ls_header
structure_tadir = ls_tadir.
rv_bool = boolc( ls_header-id IS NOT INITIAL ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
CALL FUNCTION 'BMENU_DELETE_TREE'
EXPORTING
tree_id = mv_tree_id
EXCEPTIONS
trees_do_not_exist = 1
no_authority = 2
canceled = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from BMENU_DELETE_TREE, SHI3' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_msg TYPE hier_mess,
ls_head TYPE ttree,
lt_titles TYPE TABLE OF ttreet,
lt_nodes TYPE TABLE OF hier_iface,
lt_texts TYPE TABLE OF hier_texts,
lt_refs TYPE TABLE OF hier_ref.
CALL FUNCTION 'STREE_STRUCTURE_READ'
EXPORTING
structure_id = mv_tree_id
IMPORTING
message = ls_msg
structure_header = ls_head
TABLES
description = lt_titles.
CALL FUNCTION 'STREE_HIERARCHY_READ'
EXPORTING
structure_id = mv_tree_id
read_also_texts = 'X'
all_languages = 'X'
IMPORTING
message = ls_msg
TABLES
list_of_nodes = lt_nodes
list_of_references = lt_refs
list_of_texts = lt_texts.
clear_fields( CHANGING cs_head = ls_head
ct_nodes = lt_nodes ).
io_xml->add( iv_name = 'TREE_HEAD'
ig_data = ls_head ).
io_xml->add( iv_name = 'TREE_TITLES'
ig_data = lt_titles ).
io_xml->add( iv_name = 'TREE_NODES'
ig_data = lt_nodes ).
io_xml->add( iv_name = 'TREE_REFS'
ig_data = lt_refs ).
io_xml->add( iv_name = 'TREE_TEXTS'
ig_data = lt_texts ).
ENDMETHOD.
METHOD clear_fields.
FIELD-SYMBOLS <ls_node> LIKE LINE OF ct_nodes.
CLEAR: cs_head-luser, cs_head-ldate, cs_head-ltime.
CLEAR: cs_head-fuser, cs_head-fdate, cs_head-ftime.
CLEAR: cs_head-frelease, cs_head-lrelease.
CLEAR: cs_head-responsibl.
LOOP AT ct_nodes ASSIGNING <ls_node>.
CLEAR: <ls_node>-luser, <ls_node>-ldate, <ls_node>-ltime.
CLEAR: <ls_node>-fuser, <ls_node>-fdate, <ls_node>-ftime.
CLEAR: <ls_node>-frelease, <ls_node>-lrelease.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_msg TYPE hier_mess,
ls_head TYPE ttree,
lt_titles TYPE TABLE OF ttreet,
lt_nodes TYPE TABLE OF hier_iface,
lt_texts TYPE TABLE OF hier_texts,
lt_refs TYPE TABLE OF hier_ref.
io_xml->read( EXPORTING iv_name = 'TREE_HEAD'
CHANGING cg_data = ls_head ).
io_xml->read( EXPORTING iv_name = 'TREE_TITLES'
CHANGING cg_data = lt_titles ).
io_xml->read( EXPORTING iv_name = 'TREE_NODES'
CHANGING cg_data = lt_nodes ).
io_xml->read( EXPORTING iv_name = 'TREE_REFS'
CHANGING cg_data = lt_refs ).
io_xml->read( EXPORTING iv_name = 'TREE_TEXTS'
CHANGING cg_data = lt_texts ).
IF zif_abapgit_object~exists( ) = abap_true.
zif_abapgit_object~delete( ).
ENDIF.
CALL FUNCTION 'STREE_HIERARCHY_SAVE'
EXPORTING
structure_id = mv_tree_id
structure_type = ls_head-type
structure_description = space
structure_masterlanguage = mv_language
structure_responsible = sy-uname
development_class = iv_package
IMPORTING
message = ls_msg
TABLES
list_of_nodes = lt_nodes
list_of_references = lt_refs
list_of_texts = lt_texts
structure_descriptions = lt_titles
EXCEPTIONS
no_nodes_given = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from STREE_HIERARCHY_SAVE, SHI3' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_SFSW IMPLEMENTATION.
METHOD get.
DATA: lv_switch_id TYPE sfw_switch_id.
lv_switch_id = ms_item-obj_name.
TRY.
ro_switch = cl_sfw_sw=>get_switch_from_db( lv_switch_id ).
CATCH cx_pak_invalid_data cx_pak_invalid_state cx_pak_not_authorized.
zcx_abapgit_exception=>raise( 'Error from CL_SFW_SW=>GET_SWITCH' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_data TYPE sfw_switch.
ls_data = get( )->get_header_data( ).
rv_user = ls_data-changedby.
IF rv_user IS INITIAL.
rv_user = ls_data-author.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_switch_id TYPE sfw_switch_id,
lo_switch TYPE REF TO cl_sfw_sw.
lv_switch_id = ms_item-obj_name.
TRY.
lo_switch = cl_sfw_sw=>get_switch( lv_switch_id ).
lo_switch->set_delete_flag( lv_switch_id ).
lo_switch->save_all( ).
CATCH cx_pak_invalid_data cx_pak_invalid_state cx_pak_not_authorized.
zcx_abapgit_exception=>raise( 'Error deleting Switch' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lo_switch TYPE REF TO cl_sfw_sw,
lv_switch_id TYPE sfw_switch_id,
ls_header TYPE sfw_switch,
lv_name_32 TYPE sfw_name32,
lv_name_80 TYPE sfw_name80,
lt_parent_bf TYPE sfw_bf_sw_outtab,
lt_conflicts TYPE sfw_confl_outtab.
io_xml->read( EXPORTING iv_name = 'HEADER'
CHANGING cg_data = ls_header ).
io_xml->read( EXPORTING iv_name = 'NAME32'
CHANGING cg_data = lv_name_32 ).
io_xml->read( EXPORTING iv_name = 'NAME80'
CHANGING cg_data = lv_name_80 ).
io_xml->read( EXPORTING iv_name = 'PARENT_BF'
CHANGING cg_data = lt_parent_bf ).
io_xml->read( EXPORTING iv_name = 'CONFLICTS'
CHANGING cg_data = lt_conflicts ).
lv_switch_id = ms_item-obj_name.
TRY.
lo_switch = cl_sfw_sw=>create_switch( lv_switch_id ).
CATCH cx_pak_not_authorized cx_pak_invalid_state cx_pak_invalid_data.
zcx_abapgit_exception=>raise( 'error in CL_SFW_SW=>CREATE_SWITCH' ).
ENDTRY.
ls_header-author = sy-uname.
ls_header-createdon = sy-datum.
lo_switch->set_header_data( ls_header ).
lo_switch->set_texts( p_32 = lv_name_32
p_80 = lv_name_80 ).
lo_switch->set_parent_bf( lt_parent_bf ).
lo_switch->set_conflicts( lt_conflicts ).
set_default_package( iv_package ).
lo_switch->save_all(
EXCEPTIONS
not_saved = 1
OTHERS = 2 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error in CL_SFW_SW->SAVE_ALL' ).
ENDIF.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_tadir TYPE tadir,
lv_switch_id TYPE sfw_switch_id.
lv_switch_id = ms_item-obj_name.
IF cl_sfw_sw=>check_existence( lv_switch_id ) = abap_false.
RETURN.
ENDIF.
SELECT SINGLE * FROM tadir INTO ls_tadir
WHERE pgmid = 'R3TR'
AND object = ms_item-obj_type
AND obj_name = ms_item-obj_name.
IF ls_tadir IS INITIAL.
RETURN.
ENDIF.
rv_bool = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'SFSW'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_switch TYPE REF TO cl_sfw_sw,
ls_header TYPE sfw_switch,
lv_name_32 TYPE sfw_name32,
lv_name_80 TYPE sfw_name80,
lt_parent_bf TYPE sfw_bf_sw_outtab,
lt_conflicts TYPE sfw_confl_outtab.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
lo_switch = get( ).
ls_header = lo_switch->get_header_data( ).
CLEAR: ls_header-author,
ls_header-createdon,
ls_header-changedby,
ls_header-changedon,
ls_header-timestamp.
lo_switch->get_texts(
IMPORTING
p_32 = lv_name_32
p_80 = lv_name_80 ).
lt_parent_bf = lo_switch->get_parent_bf( ).
lt_conflicts = lo_switch->get_conflicts( ).
io_xml->add( ig_data = ls_header
iv_name = 'HEADER' ).
io_xml->add( ig_data = lv_name_32
iv_name = 'NAME32' ).
io_xml->add( ig_data = lv_name_80
iv_name = 'NAME80' ).
io_xml->add( ig_data = lt_parent_bf
iv_name = 'PARENT_BF' ).
io_xml->add( ig_data = lt_conflicts
iv_name = 'CONFLICTS' ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_sfpi IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE lastuser FROM fpinterface
INTO rv_user
WHERE name = ms_item-obj_name
AND state = 'A'.
IF rv_user IS INITIAL.
SELECT SINGLE firstuser FROM fpinterface
INTO rv_user
WHERE name = ms_item-obj_name
AND state = 'A'.
ENDIF.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_name TYPE fpinterface-name.
SELECT SINGLE name FROM fpinterface
INTO lv_name
WHERE name = ms_item-obj_name
AND state = 'A'.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_name TYPE fpname,
lo_wb_interface TYPE REF TO cl_fp_wb_interface.
lo_wb_interface ?= load( ).
lv_name = ms_item-obj_name.
TRY.
lo_wb_interface->delete( lv_name ).
CATCH cx_fp_api.
zcx_abapgit_exception=>raise( 'SFPI error, delete' ).
ENDTRY.
ENDMETHOD.
METHOD load.
DATA: lv_name TYPE fpname.
lv_name = ms_item-obj_name.
TRY.
ri_wb_interface = cl_fp_wb_interface=>load( lv_name ).
CATCH cx_fp_api.
zcx_abapgit_exception=>raise( 'SFPI error, load' ).
ENDTRY.
ENDMETHOD.
METHOD interface_to_xstring.
DATA: li_fp_interface TYPE REF TO if_fp_interface,
li_wb_interface TYPE REF TO if_fp_wb_interface.
TRY.
li_wb_interface = load( ).
li_fp_interface ?= li_wb_interface->get_object( ).
rv_xstr = cl_fp_helper=>convert_interface_to_xstring( li_fp_interface ).
CATCH cx_fp_api.
zcx_abapgit_exception=>raise( 'SFPI error, interface_to_xstring' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_xstr TYPE xstring,
li_document TYPE REF TO if_ixml_document.
lv_xstr = interface_to_xstring( ).
li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xstr ).
zcl_abapgit_object_sfpf=>fix_oref( li_document ).
io_xml->set_raw( li_document->get_root_element( ) ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_xstr TYPE xstring,
lv_name TYPE fpname,
li_wb_object TYPE REF TO if_fp_wb_interface,
li_interface TYPE REF TO if_fp_interface.
lv_name = ms_item-obj_name.
lv_xstr = cl_ixml_80_20=>render_to_xstring( io_xml->get_raw( ) ).
TRY.
li_interface = cl_fp_helper=>convert_xstring_to_interface( lv_xstr ).
tadir_insert( iv_package ).
li_wb_object = cl_fp_wb_interface=>create( i_name = lv_name
i_interface = li_interface ).
li_wb_object->save( ).
li_wb_object->free( ).
CATCH cx_fp_api.
zcx_abapgit_exception=>raise( 'SFPI error, deserialize' ).
ENDTRY.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE seqg3-garg.
lv_object = |{ ms_item-obj_name }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'EFPINTERFACE'
iv_argument = lv_object ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_sfpf IMPLEMENTATION.
METHOD fix_oref.
DATA: li_iterator TYPE REF TO if_ixml_node_iterator,
lv_new TYPE n LENGTH 3,
lv_old TYPE string,
lt_map TYPE STANDARD TABLE OF string WITH DEFAULT KEY,
li_attr_map TYPE REF TO if_ixml_named_node_map,
li_attr TYPE REF TO if_ixml_node,
li_node TYPE REF TO if_ixml_node.
DEFINE _lookup.
READ TABLE lt_map FROM &1 TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
APPEND &1 TO lt_map.
READ TABLE lt_map FROM &1 TRANSPORTING NO FIELDS.
ENDIF.
lv_new = sy-tabix + 100.
END-OF-DEFINITION.
li_iterator = ii_document->create_iterator( ).
li_node = li_iterator->get_next( ).
WHILE NOT li_node IS INITIAL.
li_attr_map = li_node->get_attributes( ).
IF li_attr_map IS BOUND.
li_attr = li_attr_map->get_named_item_ns( 'href' ).
IF li_attr IS BOUND.
lv_old = li_attr->get_value( ).
IF lv_old(2) = '#o'.
_lookup lv_old+1.
li_attr->set_value( '#o' && lv_new ).
ENDIF.
ENDIF.
li_attr = li_attr_map->get_named_item_ns( 'id' ).
IF li_attr IS BOUND.
lv_old = li_attr->get_value( ).
IF lv_old(1) = 'o'.
_lookup lv_old.
li_attr->set_value( 'o' && lv_new ).
ENDIF.
ENDIF.
ENDIF.
li_node = li_iterator->get_next( ).
ENDWHILE.
ENDMETHOD.
METHOD form_to_xstring.
DATA: li_fp_form TYPE REF TO if_fp_form,
li_wb_form TYPE REF TO if_fp_wb_form.
TRY.
li_wb_form = load( ).
li_fp_form ?= li_wb_form->get_object( ).
rv_xstr = cl_fp_helper=>convert_form_to_xstring( li_fp_form ).
CATCH cx_fp_api.
zcx_abapgit_exception=>raise( 'SFPF error, form_to_xstring' ).
ENDTRY.
ENDMETHOD.
METHOD load.
DATA: lv_name TYPE fpname.
lv_name = ms_item-obj_name.
TRY.
ri_wb_form = cl_fp_wb_form=>load( lv_name ).
CATCH cx_fp_api.
zcx_abapgit_exception=>raise( 'SFPF error, load' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE lastuser FROM fplayout
INTO rv_user
WHERE name = ms_item-obj_name
AND state = 'A'.
IF rv_user IS INITIAL.
SELECT SINGLE firstuser FROM fplayout
INTO rv_user
WHERE name = ms_item-obj_name
AND state = 'A'.
ENDIF.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_name TYPE fpname,
lo_wb_form TYPE REF TO cl_fp_wb_form.
lo_wb_form ?= load( ).
lv_name = ms_item-obj_name.
TRY.
lo_wb_form->delete( lv_name ).
CATCH cx_fp_api.
zcx_abapgit_exception=>raise( 'SFPI error, delete' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_xstr TYPE xstring,
lv_name TYPE fpname,
li_wb_object TYPE REF TO if_fp_wb_form,
li_form TYPE REF TO if_fp_form.
lv_name = ms_item-obj_name.
lv_xstr = cl_ixml_80_20=>render_to_xstring( io_xml->get_raw( ) ).
TRY.
li_form = cl_fp_helper=>convert_xstring_to_form( lv_xstr ).
tadir_insert( iv_package ).
li_wb_object = cl_fp_wb_form=>create( i_name = lv_name
i_form = li_form ).
li_wb_object->save( ).
li_wb_object->free( ).
CATCH cx_fp_api.
zcx_abapgit_exception=>raise( 'SFPF error, deserialize' ).
ENDTRY.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_name TYPE fpname.
SELECT SINGLE name FROM fplayout
INTO lv_name
WHERE name = ms_item-obj_name
AND state = 'A'.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_xstr TYPE xstring,
li_document TYPE REF TO if_ixml_document.
lv_xstr = form_to_xstring( ).
li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xstr ).
fix_oref( li_document ).
io_xml->set_raw( li_document->get_root_element( ) ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE seqg3-garg.
lv_object = |{ ms_item-obj_name }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'EFPFORM'
iv_argument = lv_object ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_SFBS IMPLEMENTATION.
METHOD get.
DATA: lv_bfset TYPE sfw_bset.
lv_bfset = ms_item-obj_name.
TRY.
ro_bfs = cl_sfw_bfs=>get_bfs( lv_bfset ).
ro_bfs->free( ).
ro_bfs = cl_sfw_bfs=>get_bfs( lv_bfset ).
CATCH cx_pak_invalid_data cx_pak_invalid_state cx_pak_not_authorized.
zcx_abapgit_exception=>raise( 'Error from CL_SFW_BFS=>GET_BFS' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_data TYPE sfw_bs.
ls_data = get( )->get_header_data( ).
rv_user = ls_data-changedby.
IF rv_user IS INITIAL.
rv_user = ls_data-author.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_bfset TYPE sfw_bset,
lt_delete TYPE sfw_bstab,
lt_msgtab TYPE sprot_u_tab.
lv_bfset = ms_item-obj_name.
APPEND lv_bfset TO lt_delete.
cl_sfw_activate=>delete_sfbs( EXPORTING p_bsets = lt_delete
IMPORTING p_msgtab = lt_msgtab ).
READ TABLE lt_msgtab WITH KEY severity = 'E' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
zcx_abapgit_exception=>raise( 'Error deleting SFBS' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_bfset TYPE sfw_bset,
lo_bfs TYPE REF TO cl_sfw_bfs,
ls_header TYPE sfw_bs,
lv_name_32 TYPE sfw_name32,
lv_name_80 TYPE sfw_name80,
lt_assigned_bf TYPE sfw_bfbs_outtab,
lt_nested_bfs TYPE sfw_bsbs_outtab,
lt_parent_bfs TYPE sfw_bs_bs_parent_outtab.
io_xml->read( EXPORTING iv_name = 'HEADER'
CHANGING cg_data = ls_header ).
io_xml->read( EXPORTING iv_name = 'NAME32'
CHANGING cg_data = lv_name_32 ).
io_xml->read( EXPORTING iv_name = 'NAME80'
CHANGING cg_data = lv_name_80 ).
io_xml->read( EXPORTING iv_name = 'ASSIGNED_BF'
CHANGING cg_data = lt_assigned_bf ).
io_xml->read( EXPORTING iv_name = 'NESTED_BFS'
CHANGING cg_data = lt_nested_bfs ).
io_xml->read( EXPORTING iv_name = 'PARENT_BFS'
CHANGING cg_data = lt_parent_bfs ).
lv_bfset = ms_item-obj_name.
TRY.
lo_bfs = cl_sfw_bfs=>create_bfs( lv_bfset ).
CATCH cx_pak_not_authorized cx_pak_invalid_state cx_pak_invalid_data.
zcx_abapgit_exception=>raise( 'error in CL_SFW_BFS=>CREATE_BFS' ).
ENDTRY.
ls_header-author = sy-uname.
ls_header-createdon = sy-datum.
lo_bfs->set_header_data( ls_header ).
lo_bfs->set_texts( p_32 = lv_name_32
p_80 = lv_name_80 ).
lo_bfs->set_assigned_bf( lt_assigned_bf ).
lo_bfs->set_assigned_bfs( lt_nested_bfs ).
lo_bfs->set_nested_parent( lt_parent_bfs ).
set_default_package( iv_package ).
lo_bfs->save_all( ).
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_tadir TYPE tadir,
lv_bfset TYPE sfw_bset.
lv_bfset = ms_item-obj_name.
IF cl_sfw_bfs=>check_existence( lv_bfset ) = abap_false.
RETURN.
ENDIF.
SELECT SINGLE * FROM tadir INTO ls_tadir
WHERE pgmid = 'R3TR'
AND object = ms_item-obj_type
AND obj_name = ms_item-obj_name.
IF ls_tadir IS INITIAL.
RETURN.
ENDIF.
rv_bool = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'SFBS'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_bfs TYPE REF TO cl_sfw_bfs,
ls_header TYPE sfw_bs,
lv_name_32 TYPE sfw_name32,
lv_name_80 TYPE sfw_name80,
lt_assigned_bf TYPE sfw_bfbs_outtab,
lt_nested_bfs TYPE sfw_bsbs_outtab,
lt_parent_bfs TYPE sfw_bs_bs_parent_outtab.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
lo_bfs = get( ).
ls_header = lo_bfs->get_header_data( ).
CLEAR: ls_header-author,
ls_header-createdon,
ls_header-changedby,
ls_header-changedon,
ls_header-timestamp.
lo_bfs->get_texts(
IMPORTING
p_32 = lv_name_32
p_80 = lv_name_80 ).
lt_assigned_bf = lo_bfs->get_assigned_bf( ).
lt_nested_bfs = lo_bfs->get_nested_bfs( ).
lt_parent_bfs = lo_bfs->get_nested_parent( ).
io_xml->add( ig_data = ls_header
iv_name = 'HEADER' ).
io_xml->add( ig_data = lv_name_32
iv_name = 'NAME32' ).
io_xml->add( ig_data = lv_name_80
iv_name = 'NAME80' ).
io_xml->add( ig_data = lt_assigned_bf
iv_name = 'ASSIGNED_BF' ).
io_xml->add( ig_data = lt_nested_bfs
iv_name = 'NESTED_BFS' ).
io_xml->add( ig_data = lt_parent_bfs
iv_name = 'PARENT_BFS' ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_SFBF IMPLEMENTATION.
METHOD get.
DATA: lv_bf TYPE sfw_bfunction.
lv_bf = ms_item-obj_name.
TRY.
ro_bf = cl_sfw_bf=>get_bf( lv_bf ).
ro_bf->free( ).
ro_bf = cl_sfw_bf=>get_bf( lv_bf ).
CATCH cx_pak_invalid_data cx_pak_invalid_state cx_pak_not_authorized.
zcx_abapgit_exception=>raise( 'Error from CL_SFW_BF=>GET_BF' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_data TYPE sfw_bf.
ls_data = get( )->get_header_data( ).
rv_user = ls_data-changedby.
IF rv_user IS INITIAL.
rv_user = ls_data-author.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_bf TYPE sfw_bfunction,
lt_delete TYPE sfw_bftab,
lt_msgtab TYPE sprot_u_tab.
lv_bf = ms_item-obj_name.
APPEND lv_bf TO lt_delete.
cl_sfw_activate=>delete_sfbf( EXPORTING p_bfuncts = lt_delete
IMPORTING p_msgtab = lt_msgtab ).
READ TABLE lt_msgtab WITH KEY severity = 'E' TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
zcx_abapgit_exception=>raise( 'Error deleting SFBF' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_bf TYPE sfw_bfunction,
lo_bf TYPE REF TO cl_sfw_bf,
ls_header TYPE sfw_bf,
lv_name_32 TYPE sfw_name32,
lv_name_80 TYPE sfw_name80,
lt_assigned_switches TYPE sfw_swbf_outtab,
lt_dependancies TYPE sfw_depend_outtab,
ls_sfw_bfc_kw TYPE sfw_bfc_kw,
ls_sfw_bfc_tc TYPE sfw_bfc_tc,
ls_sfw_bfc_rn TYPE sfw_bfc_rn,
lt_parent_bfs TYPE sfw_bs_bf_outtab.
io_xml->read( EXPORTING iv_name = 'HEADER'
CHANGING cg_data = ls_header ).
io_xml->read( EXPORTING iv_name = 'NAME32'
CHANGING cg_data = lv_name_32 ).
io_xml->read( EXPORTING iv_name = 'NAME80'
CHANGING cg_data = lv_name_80 ).
io_xml->read( EXPORTING iv_name = 'ASSIGNED_SWITCHES'
CHANGING cg_data = lt_assigned_switches ).
io_xml->read( EXPORTING iv_name = 'DEPENDANCIES'
CHANGING cg_data = lt_dependancies ).
io_xml->read( EXPORTING iv_name = 'CONTENT_KW'
CHANGING cg_data = ls_sfw_bfc_kw ).
io_xml->read( EXPORTING iv_name = 'CONTENT_TC'
CHANGING cg_data = ls_sfw_bfc_tc ).
io_xml->read( EXPORTING iv_name = 'CONTENT_RN'
CHANGING cg_data = ls_sfw_bfc_rn ).
io_xml->read( EXPORTING iv_name = 'PARENT_BFS'
CHANGING cg_data = lt_parent_bfs ).
lv_bf = ms_item-obj_name.
TRY.
lo_bf = cl_sfw_bf=>create_bf( lv_bf ).
CATCH cx_pak_not_authorized cx_pak_invalid_state cx_pak_invalid_data.
zcx_abapgit_exception=>raise( 'error in CL_SFW_BF=>CREATE_BF' ).
ENDTRY.
ls_header-author = sy-uname.
ls_header-createdon = sy-datum.
lo_bf->set_header_data( ls_header ).
lo_bf->set_texts( p_32 = lv_name_32
p_80 = lv_name_80 ).
lo_bf->set_assigned_switches( lt_assigned_switches ).
lo_bf->set_excluded_bf( lt_dependancies ).
lo_bf->set_content_data(
im_sfw_bfc_kw = ls_sfw_bfc_kw
im_sfw_bfc_rn = ls_sfw_bfc_rn
im_sfw_bfc_tc = ls_sfw_bfc_tc ).
lo_bf->set_parent_bfs( lt_parent_bfs ).
set_default_package( iv_package ).
lo_bf->save_all( ).
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_tadir TYPE tadir,
lv_bf TYPE sfw_bfunction.
lv_bf = ms_item-obj_name.
IF cl_sfw_bf=>check_existence( lv_bf ) = abap_false.
RETURN.
ENDIF.
SELECT SINGLE * FROM tadir INTO ls_tadir
WHERE pgmid = 'R3TR'
AND object = ms_item-obj_type
AND obj_name = ms_item-obj_name.
IF ls_tadir IS INITIAL.
RETURN.
ENDIF.
rv_bool = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'SFBF'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_bf TYPE REF TO cl_sfw_bf,
ls_header TYPE sfw_bf,
lv_name_32 TYPE sfw_name32,
lv_name_80 TYPE sfw_name80,
lt_assigned_switches TYPE sfw_swbf_outtab,
lt_dependancies TYPE sfw_depend_outtab,
ls_sfw_bfc_kw TYPE sfw_bfc_kw,
ls_sfw_bfc_tc TYPE sfw_bfc_tc,
ls_sfw_bfc_rn TYPE sfw_bfc_rn,
lt_parent_bfs TYPE sfw_bs_bf_outtab.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
lo_bf = get( ).
ls_header = lo_bf->get_header_data( ).
CLEAR: ls_header-author,
ls_header-createdon,
ls_header-changedby,
ls_header-changedon,
ls_header-timestamp.
lo_bf->get_texts(
IMPORTING
p_32 = lv_name_32
p_80 = lv_name_80 ).
lt_assigned_switches = lo_bf->get_assigned_switches( ).
lt_dependancies = lo_bf->get_excluded_bf( ).
lo_bf->get_content_data(
IMPORTING
ex_sfw_bfc_kw = ls_sfw_bfc_kw
ex_sfw_bfc_tc = ls_sfw_bfc_tc
ex_sfw_bfc_rn = ls_sfw_bfc_rn ).
lt_parent_bfs = lo_bf->get_parent_bfs( ).
io_xml->add( ig_data = ls_header
iv_name = 'HEADER' ).
io_xml->add( ig_data = lv_name_32
iv_name = 'NAME32' ).
io_xml->add( ig_data = lv_name_80
iv_name = 'NAME80' ).
io_xml->add( ig_data = lt_assigned_switches
iv_name = 'ASSIGNED_SWITCHES' ).
io_xml->add( ig_data = lt_dependancies
iv_name = 'DEPENDANCIES' ).
io_xml->add( ig_data = ls_sfw_bfc_kw
iv_name = 'CONTENT_KW' ).
io_xml->add( ig_data = ls_sfw_bfc_tc
iv_name = 'CONTENT_TC' ).
io_xml->add( ig_data = ls_sfw_bfc_rn
iv_name = 'CONTENT_RN' ).
io_xml->add( ig_data = lt_parent_bfs
iv_name = 'PARENT_BFS' ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_scp1 IMPLEMENTATION.
METHOD adjust_inbound.
FIELD-SYMBOLS: <ls_scprvals> TYPE scprvals,
<ls_scprreca> TYPE scprreca.
LOOP AT cs_scp1-scprvals ASSIGNING <ls_scprvals>.
SHIFT <ls_scprvals>-recnumber RIGHT DELETING TRAILING space.
ENDLOOP.
LOOP AT cs_scp1-scprreca ASSIGNING <ls_scprreca>.
SHIFT <ls_scprreca>-recnumber RIGHT DELETING TRAILING space.
ENDLOOP.
ENDMETHOD.
METHOD adjust_outbound.
FIELD-SYMBOLS: <ls_scprvals> TYPE scprvals,
<ls_scprreca> TYPE scprreca.
LOOP AT cs_scp1-scprvals ASSIGNING <ls_scprvals>.
CONDENSE <ls_scprvals>-recnumber.
ENDLOOP.
LOOP AT cs_scp1-scprreca ASSIGNING <ls_scprreca>.
CONDENSE <ls_scprreca>-recnumber.
ENDLOOP.
ENDMETHOD.
METHOD dequeue.
DATA: lv_id TYPE scpr_id.
lv_id = ms_item-obj_name.
CALL FUNCTION 'SCPR_SV_DEQUEUE_BCSET'
EXPORTING
bcset_id = lv_id.
ENDMETHOD.
METHOD enqueue.
DATA: lv_id TYPE scpr_id.
lv_id = ms_item-obj_name.
CALL FUNCTION 'SCPR_SV_ENQUEUE_BCSET'
EXPORTING
bcset_id = lv_id
EXCEPTIONS
is_already_locked = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |SCP1 locking error| ).
ENDIF.
ENDMETHOD.
METHOD load.
CALL FUNCTION 'SCPR_TEXT_GET'
EXPORTING
profid = cs_scp1-scprattr-id
category = cs_scp1-scprattr-category
TABLES
texts = cs_scp1-scprtext
EXCEPTIONS
no_text_found = 1.
CALL FUNCTION 'SCPR_TEMPL_DB_VALS_GET_DETAIL'
EXPORTING
profid = cs_scp1-scprattr-id
category = cs_scp1-scprattr-category
TABLES
values = cs_scp1-scprvals
valuesl = cs_scp1-scprvall
recattr = cs_scp1-scprreca.
CALL FUNCTION 'SCPR_TEMPL_DB_FLDTXTVAR_GET'
EXPORTING
bcset_id = cs_scp1-scprattr-id
category = cs_scp1-scprattr-category
TABLES
it_fldv = cs_scp1-scprfldv.
ENDMETHOD.
METHOD save.
DATA: ls_scp1 TYPE ty_scp1,
ls_text TYPE scprtext.
ls_scp1 = is_scp1.
READ TABLE ls_scp1-scprtext INTO ls_text WITH KEY langu = sy-langu.
CALL FUNCTION 'SCPR_TEMPL_MN_TEMPLATE_SAVE'
EXPORTING
profid = ls_scp1-scprattr-id
proftext = ls_text-text
category = ls_scp1-scprattr-category
cli_dep = ls_scp1-scprattr-cli_dep
cli_cas = ls_scp1-scprattr-cli_cas
reftype = ls_scp1-scprattr-reftype
refname = ls_scp1-scprattr-refname
orgid = ls_scp1-scprattr-orgid
component = ls_scp1-scprattr-component
minrelease = ls_scp1-scprattr-minrelease
maxrelease = ls_scp1-scprattr-maxrelease
act_info = ls_scp1-scprattr-act_info
bcset_type = ls_scp1-scprattr-type
fldtxtvar_supplied = 'YES'
with_transp_insert = abap_false
with_progress_indicator = abap_true
remove_denied_data = abap_true
ask_for_cont_after_remove = abap_true
TABLES
values = ls_scp1-scprvals
valuesl = ls_scp1-scprvall
recattr = ls_scp1-scprreca
it_fldv = ls_scp1-scprfldv
texts = ls_scp1-scprtext
EXCEPTIONS
user_abort = 1
error_in_transport_layer = 2
inconsistent_data = 3
database_error = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error saving SCP1, { sy-tabix }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE modifier INTO rv_user FROM scprattr
WHERE id = ms_item-obj_name
AND version = 'N'.
IF sy-subrc <> 0 OR rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_id TYPE scpr_id.
lv_id = ms_item-obj_name.
enqueue( ).
CALL FUNCTION 'SCPR_CTRL_DELETE'
EXPORTING
profid = lv_id
EXCEPTIONS
user_abort = 1
profile_dont_exist = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |error while deleting SCP1, { sy-subrc }| ).
ENDIF.
dequeue( ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_scp1 TYPE ty_scp1.
io_xml->read(
EXPORTING iv_name = 'SCP1'
CHANGING cg_data = ls_scp1 ).
adjust_inbound( CHANGING cs_scp1 = ls_scp1 ).
IF ls_scp1-scprattr-type = 'TMP'.
zcx_abapgit_exception=>raise( |todo, SCP1| ).
ELSE.
save( ls_scp1 ).
ENDIF.
dequeue( ).
tadir_insert( iv_package ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_rc TYPE sy-subrc,
lv_profid TYPE scprattr-id.
lv_profid = ms_item-obj_name.
CALL FUNCTION 'SCPR_BCSET_EXISTS'
EXPORTING
profid = lv_profid
IMPORTING
rc = lv_rc.
rv_bool = boolc( lv_rc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lv_display_only TYPE scpr_txt20,
lv_bcset_id TYPE scpr_id.
lv_display_only = abap_false.
lv_bcset_id = ms_item-obj_name.
EXPORT scpr3_display_only = lv_display_only
scpr3_bcset_id = lv_bcset_id
TO MEMORY ID 'SCPR3_PARAMETER'.
SUBMIT scpr3 AND RETURN.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_scp1 TYPE ty_scp1.
ls_scp1-scprattr-id = ms_item-obj_name.
CALL FUNCTION 'SCPR_DB_ATTR_GET_DETAIL'
EXPORTING
profid = ls_scp1-scprattr-id
IMPORTING
proftype = ls_scp1-scprattr-type
cli_dep = ls_scp1-scprattr-cli_dep
cli_cas = ls_scp1-scprattr-cli_cas
reftype = ls_scp1-scprattr-reftype
refname = ls_scp1-scprattr-refname
component = ls_scp1-scprattr-component
minrelease = ls_scp1-scprattr-minrelease
maxrelease = ls_scp1-scprattr-maxrelease
orgid = ls_scp1-scprattr-orgid
act_info = ls_scp1-scprattr-act_info.
IF ls_scp1-scprattr-type = 'TMP'.
zcx_abapgit_exception=>raise( |todo, SCP1| ).
ELSE.
load( CHANGING cs_scp1 = ls_scp1 ).
ENDIF.
adjust_outbound( CHANGING cs_scp1 = ls_scp1 ).
io_xml->add(
iv_name = 'SCP1'
ig_data = ls_scp1 ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_sapc IMPLEMENTATION.
METHOD get_data_class_name.
r_data_class_name = 'CL_APC_APPLICATION_OBJ_DATA'.
ENDMETHOD.
METHOD get_data_structure_name.
r_data_structure_name = 'APC_APPLICATION_COMPLETE'.
ENDMETHOD.
METHOD get_persistence_class_name.
r_persistence_class_name = 'CL_APC_APPLICATION_OBJ_PERS'.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_samc IMPLEMENTATION.
METHOD get_data_class_name.
r_data_class_name = 'CL_AMC_APPLICATION_OBJ_DATA'.
ENDMETHOD.
METHOD get_data_structure_name.
r_data_structure_name = 'AMC_APPLICATION_COMPLETE'.
ENDMETHOD.
METHOD get_persistence_class_name.
r_persistence_class_name = 'CL_AMC_APPLICATION_OBJ_PERS'.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_PROG IMPLEMENTATION.
METHOD deserialize_texts.
DATA: lt_tpool_i18n TYPE tt_tpool_i18n,
lt_tpool TYPE textpool_table.
FIELD-SYMBOLS <ls_tpool> LIKE LINE OF lt_tpool_i18n.
io_xml->read( EXPORTING iv_name = 'I18N_TPOOL'
CHANGING cg_data = lt_tpool_i18n ).
LOOP AT lt_tpool_i18n ASSIGNING <ls_tpool>.
lt_tpool = read_tpool( <ls_tpool>-textpool ).
deserialize_textpool( iv_program = ms_item-obj_name
iv_language = <ls_tpool>-language
it_tpool = lt_tpool ).
ENDLOOP.
ENDMETHOD.
METHOD is_program_locked.
rv_is_program_locked = exists_a_lock_entry_for( iv_lock_object = 'ESRDIRE'
iv_argument = |{ ms_item-obj_name }| ).
ENDMETHOD.
METHOD serialize_texts.
DATA: lt_tpool_i18n TYPE tt_tpool_i18n,
lt_tpool TYPE textpool_table.
FIELD-SYMBOLS <ls_tpool> LIKE LINE OF lt_tpool_i18n.
" Table d010tinf stores info. on languages in which program is maintained
" Select all active translations of program texts
" Skip master language - it was already serialized
SELECT DISTINCT language
INTO CORRESPONDING FIELDS OF TABLE lt_tpool_i18n
FROM d010tinf
WHERE r3state = 'A'
AND prog = ms_item-obj_name
AND language <> mv_language.
SORT lt_tpool_i18n BY language ASCENDING.
LOOP AT lt_tpool_i18n ASSIGNING <ls_tpool>.
READ TEXTPOOL ms_item-obj_name
LANGUAGE <ls_tpool>-language
INTO lt_tpool.
<ls_tpool>-textpool = add_tpool( lt_tpool ).
ENDLOOP.
IF lines( lt_tpool_i18n ) > 0.
io_xml->add( iv_name = 'I18N_TPOOL'
ig_data = lt_tpool_i18n ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE unam FROM reposrc INTO rv_user
WHERE progname = ms_item-obj_name
AND r3state = 'A'.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_program LIKE sy-repid.
lv_program = ms_item-obj_name.
CALL FUNCTION 'RS_DELETE_PROGRAM'
EXPORTING
program = lv_program
suppress_popup = abap_true
force_delete_used_includes = abap_true
EXCEPTIONS
enqueue_lock = 1
object_not_found = 2
permission_failure = 3
reject_deletion = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from RS_DELETE_PROGRAM: { sy-subrc }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_program_name TYPE programm,
ls_progdir TYPE ty_progdir,
lt_tpool TYPE textpool_table,
lt_dynpros TYPE ty_dynpro_tt,
lt_tpool_ext TYPE zif_abapgit_definitions=>ty_tpool_tt,
ls_cua TYPE ty_cua,
lt_source TYPE abaptxt255_tab.
lv_program_name = ms_item-obj_name.
lt_source = mo_files->read_abap( ).
io_xml->read( EXPORTING iv_name = 'TPOOL'
CHANGING cg_data = lt_tpool_ext ).
lt_tpool = read_tpool( lt_tpool_ext ).
io_xml->read( EXPORTING iv_name = 'PROGDIR'
CHANGING cg_data = ls_progdir ).
deserialize_program( is_progdir = ls_progdir
it_source = lt_source
it_tpool = lt_tpool
iv_package = iv_package ).
io_xml->read( EXPORTING iv_name = 'DYNPROS'
CHANGING cg_data = lt_dynpros ).
deserialize_dynpros( lt_dynpros ).
io_xml->read( EXPORTING iv_name = 'CUA'
CHANGING cg_data = ls_cua ).
deserialize_cua( iv_program_name = lv_program_name
is_cua = ls_cua ).
" Texts deserializing (English)
deserialize_textpool( iv_program = lv_program_name
it_tpool = lt_tpool ).
" Texts deserializing (translations)
deserialize_texts( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_progname TYPE reposrc-progname.
SELECT SINGLE progname FROM reposrc INTO lv_progname
WHERE progname = ms_item-obj_name
AND r3state = 'A'.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = check_prog_changed_since(
iv_program = ms_item-obj_name
iv_timestamp = iv_timestamp ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
IF is_program_locked( ) = abap_true
OR is_any_dynpro_locked( ms_item-obj_name ) = abap_true
OR is_cua_locked( ms_item-obj_name ) = abap_true
OR is_text_locked( ms_item-obj_name ) = abap_true.
rv_is_locked = abap_true.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'PROG'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
ASSERT NOT ms_item-obj_name CP '*=E'.
serialize_program( io_xml = io_xml
is_item = ms_item
io_files = mo_files ).
" Texts serializing (translations)
serialize_texts( io_xml ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_PRAG IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_pragma TYPE REF TO cl_abap_pragma.
TRY.
lo_pragma = cl_abap_pragma=>get_ref( ms_item-obj_name ).
lo_pragma->delete( ).
CATCH cx_abap_pragma_not_exists.
_raise_pragma_not_exists( ).
CATCH cx_abap_pragma_enqueue.
_raise_pragma_enqueue( ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_pragma TYPE ty_pragma,
lo_pragma TYPE REF TO cl_abap_pragma.
TRY.
io_xml->read(
EXPORTING
iv_name = 'PRAG'
CHANGING
cg_data = ls_pragma ).
lo_pragma = cl_abap_pragma=>create( p_pragma = ms_item-obj_name
p_package = iv_package ).
lo_pragma->set_info( p_description = ls_pragma-description
p_signature = ls_pragma-signature
p_extension = ls_pragma-extension ).
lo_pragma->save( ).
CATCH cx_abap_pragma_not_exists.
_raise_pragma_not_exists( ).
CATCH cx_abap_pragma_exists.
_raise_pragma_exists( ).
CATCH cx_abap_pragma_enqueue.
_raise_pragma_enqueue( ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
TRY.
cl_abap_pragma=>get_ref( ms_item-obj_name ).
CATCH cx_abap_pragma_not_exists.
rv_bool = abap_false.
RETURN.
ENDTRY.
rv_bool = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_pragma TYPE REF TO cl_abap_pragma,
ls_pragma TYPE zcl_abapgit_object_prag=>ty_pragma.
TRY.
lo_pragma = cl_abap_pragma=>get_ref( ms_item-obj_name ).
ls_pragma-pragma = lo_pragma->pragma.
ls_pragma-extension = lo_pragma->extension.
ls_pragma-signature = lo_pragma->signature.
ls_pragma-description = lo_pragma->description.
io_xml->add( iv_name = 'PRAG'
ig_data = ls_pragma ).
CATCH cx_abap_pragma_not_exists.
_raise_pragma_not_exists( ).
ENDTRY.
ENDMETHOD.
METHOD _raise_pragma_enqueue.
zcx_abapgit_exception=>raise( |Pragma { ms_item-obj_name } enqueue error| ).
ENDMETHOD.
METHOD _raise_pragma_exists.
zcx_abapgit_exception=>raise( |Pragma { ms_item-obj_name } exists| ).
ENDMETHOD.
METHOD _raise_pragma_not_exists.
zcx_abapgit_exception=>raise( |Pragma { ms_item-obj_name } doesn't exist| ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_pinf IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE changed_by FROM intf INTO rv_user
WHERE intf_name = ms_item-obj_name.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_pack_name TYPE intf-pack_name,
lv_main_pack TYPE tdevc-mainpack.
SELECT SINGLE pack_name FROM intf INTO lv_pack_name
WHERE intf_name = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
IF rv_bool = abap_true.
SELECT SINGLE mainpack FROM tdevc INTO lv_main_pack
WHERE devclass = lv_pack_name. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_pinf TYPE ty_pinf,
lv_name TYPE scomifnam,
lt_elements TYPE ty_elements,
li_interface TYPE REF TO if_package_interface.
FIELD-SYMBOLS: <lg_any> TYPE any,
<li_element> LIKE LINE OF lt_elements,
<ls_element> LIKE LINE OF ls_pinf-elements.
lv_name = ms_item-obj_name.
cl_package_interface=>load_package_interface(
EXPORTING
i_package_interface_name = lv_name
i_force_reload = abap_true
IMPORTING
e_package_interface = li_interface ).
li_interface->get_all_attributes(
IMPORTING e_package_interface_data = ls_pinf-attributes ).
CLEAR: ls_pinf-attributes-pack_name,
ls_pinf-attributes-author,
ls_pinf-attributes-created_by,
ls_pinf-attributes-created_on,
ls_pinf-attributes-changed_by,
ls_pinf-attributes-changed_on,
ls_pinf-attributes-tadir_devc.
ASSIGN COMPONENT 'SW_COMP_LOGICAL_PACKAGE' OF STRUCTURE ls_pinf-attributes TO <lg_any>.
IF sy-subrc = 0.
CLEAR <lg_any>.
ENDIF.
ASSIGN COMPONENT 'SW_COMP_TADIR_PACKAGE' OF STRUCTURE ls_pinf-attributes TO <lg_any>.
IF sy-subrc = 0.
CLEAR <lg_any>.
ENDIF.
li_interface->get_elements( IMPORTING e_elements = lt_elements ).
LOOP AT lt_elements ASSIGNING <li_element>.
APPEND INITIAL LINE TO ls_pinf-elements ASSIGNING <ls_element>.
<li_element>->get_all_attributes( IMPORTING e_element_data = <ls_element> ).
CLEAR <ls_element>-elem_pack.
ENDLOOP.
io_xml->add( ig_data = ls_pinf
iv_name = 'PINF' ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: li_interface TYPE REF TO if_package_interface,
ls_pinf TYPE ty_pinf.
io_xml->read( EXPORTING iv_name = 'PINF'
CHANGING cg_data = ls_pinf ).
li_interface = create_or_load(
is_pinf = ls_pinf
iv_package = iv_package ).
update_attributes(
is_pinf = ls_pinf
ii_interface = li_interface ).
update_elements(
is_pinf = ls_pinf
ii_interface = li_interface ).
ENDMETHOD.
METHOD update_attributes.
DATA: ls_sign TYPE scompisign,
lv_changeable TYPE flag.
ii_interface->get_changeable( IMPORTING e_changeable = lv_changeable ).
IF lv_changeable = abap_false.
ii_interface->set_changeable( abap_true ).
ENDIF.
ls_sign-descript = abap_true.
ls_sign-pinftype = abap_true.
ls_sign-restricted = abap_true.
ls_sign-default_if = abap_true.
ls_sign-def_sever = abap_true.
ls_sign-acl_flag = abap_true.
ls_sign-pifstablty = abap_true.
ls_sign-release_status = abap_true.
ii_interface->set_all_attributes(
i_package_interface_data = is_pinf-attributes
i_data_sign = ls_sign ).
ii_interface->save( ).
ii_interface->set_changeable( abap_false ).
ENDMETHOD.
METHOD update_elements.
DATA: lt_existing TYPE ty_elements,
lt_add TYPE scomeldata,
lv_index TYPE i,
lv_found TYPE abap_bool,
ls_attr TYPE scomeldtln.
FIELD-SYMBOLS: <li_element> LIKE LINE OF lt_existing,
<ls_element> LIKE LINE OF is_pinf-elements.
ii_interface->set_elements_changeable( abap_true ).
ii_interface->get_elements( IMPORTING e_elements = lt_existing ).
LOOP AT is_pinf-elements ASSIGNING <ls_element>.
lv_found = abap_false.
LOOP AT lt_existing ASSIGNING <li_element>.
lv_index = sy-tabix.
<li_element>->get_all_attributes( IMPORTING e_element_data = ls_attr ).
IF <ls_element>-elem_type = ls_attr-elem_type
AND <ls_element>-elem_key = ls_attr-elem_key.
DELETE lt_existing INDEX lv_index.
CONTINUE. " current loop
ENDIF.
ENDLOOP.
IF lv_found = abap_false.
APPEND <ls_element> TO lt_add.
ENDIF.
ENDLOOP.
ii_interface->remove_elements( lt_existing ).
ii_interface->add_elements( lt_add ).
ii_interface->save_elements( ).
ii_interface->set_elements_changeable( abap_false ).
ENDMETHOD.
METHOD create_or_load.
IF zif_abapgit_object~exists( ) = abap_false.
cl_package_interface=>create_new_package_interface(
EXPORTING
i_pkg_interface_name = is_pinf-attributes-intf_name
i_publisher_pkg_name = iv_package
IMPORTING
e_package_interface = ri_interface
EXCEPTIONS
object_already_existing = 1
object_just_created = 2
interface_name_invalid = 3
unexpected_error = 4
OTHERS = 7 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error creating new package interface' ).
ENDIF.
ELSE.
cl_package_interface=>load_package_interface(
EXPORTING
i_package_interface_name = is_pinf-attributes-intf_name
i_force_reload = abap_true
IMPORTING
e_package_interface = ri_interface
EXCEPTIONS
db_read_error = 1
unexpected_error = 2
object_not_existing = 3
shorttext_not_existing = 4
object_locked_and_modified = 5
OTHERS = 6 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error loading package interface' ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD delete_elements.
DATA: lt_elements TYPE ty_elements.
FIELD-SYMBOLS: <li_element> LIKE LINE OF lt_elements.
ii_interface->set_elements_changeable( abap_true ).
ii_interface->get_elements( IMPORTING e_elements = lt_elements ).
LOOP AT lt_elements ASSIGNING <li_element>.
<li_element>->delete( ).
ENDLOOP.
ii_interface->save_elements( ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_name TYPE scomifnam,
li_interface TYPE REF TO if_package_interface.
lv_name = ms_item-obj_name.
cl_package_interface=>load_package_interface(
EXPORTING
i_package_interface_name = lv_name
IMPORTING
e_package_interface = li_interface
EXCEPTIONS
db_read_error = 1
unexpected_error = 2
object_not_existing = 3
shorttext_not_existing = 4
object_locked_and_modified = 5
OTHERS = 6 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error loading package interface, delete' ).
ENDIF.
delete_elements( li_interface ).
li_interface->set_changeable( abap_true ).
li_interface->delete( ).
li_interface->save( ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'PINF'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_para IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_paramid TYPE tpara-paramid.
SELECT SINGLE paramid FROM tpara INTO lv_paramid
WHERE paramid = ms_item-obj_name. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_tpara TYPE tpara,
ls_tparat TYPE tparat.
SELECT SINGLE * FROM tpara INTO ls_tpara
WHERE paramid = ms_item-obj_name. "#EC CI_GENBUFF
IF sy-subrc <> 0.
RETURN.
ENDIF.
SELECT SINGLE * FROM tparat INTO ls_tparat
WHERE paramid = ms_item-obj_name
AND sprache = mv_language. "#EC CI_GENBUFF "#EC CI_SUBRC
io_xml->add( iv_name = 'TPARA'
ig_data = ls_tpara ).
io_xml->add( iv_name = 'TPARAT'
ig_data = ls_tparat ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_mode TYPE c LENGTH 1,
ls_tpara TYPE tpara,
ls_tparat TYPE tparat.
SELECT SINGLE * FROM tpara INTO ls_tpara
WHERE paramid = ms_item-obj_name. "#EC CI_GENBUFF
IF sy-subrc = 0.
lv_mode = 'M'.
ELSE.
lv_mode = 'I'.
ENDIF.
io_xml->read( EXPORTING iv_name = 'TPARA'
CHANGING cg_data = ls_tpara ).
io_xml->read( EXPORTING iv_name = 'TPARAT'
CHANGING cg_data = ls_tparat ).
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = ms_item-obj_name
object_class = 'PARA'
mode = lv_mode
global_lock = abap_true
devclass = iv_package
master_language = mv_language
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT, PARA' ).
ENDIF.
MODIFY tpara FROM ls_tpara. "#EC CI_SUBRC
ASSERT sy-subrc = 0.
MODIFY tparat FROM ls_tparat. "#EC CI_SUBRC
ASSERT sy-subrc = 0.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
" We can't use FM RS_PARAMETER_DELETE because of the popup to confirm
"Therefore we have to reimplement most of the FMs logic
DATA: lv_paramid TYPE tpara-paramid,
ls_transpkey TYPE trkey.
lv_paramid = ms_item-obj_name.
CALL FUNCTION 'RS_ACCESS_PERMISSION'
EXPORTING
global_lock = abap_true
language_upd_exit = 'RS_PARAMETER_LANGUAGE_EXIT' " Name FuBa for maintenance language change
object = lv_paramid
object_class = ms_item-obj_type
suppress_language_check = space
EXCEPTIONS
canceled_in_corr = 1
enqueued_by_user = 2
enqueue_system_failure = 3
illegal_parameter_values = 4
locked_by_author = 5
no_modify_permission = 6
no_show_permission = 7
permission_failure = 8
request_language_denied = 9
OTHERS = 10.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_PRAMETER_DELETE' ).
ENDIF.
SELECT COUNT(*) FROM cross WHERE ( type = 'P' OR
type = 'Q' )
AND name = lv_paramid.
IF sy-subrc = 0.
zcx_abapgit_exception=>raise( 'PARA: Parameter is still used' ).
ELSE.
SELECT COUNT(*) FROM dd04l BYPASSING BUFFER
WHERE memoryid = lv_paramid
AND as4local = 'A'.
IF sy-subrc = 0.
zcx_abapgit_exception=>raise( 'PARA: Parameter is still used' ).
ENDIF.
ENDIF.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
global_lock = abap_true
object = lv_paramid
object_class = 'PARA'
mode = 'D'
IMPORTING
transport_key = ls_transpkey
EXCEPTIONS
cancelled = 01
permission_failure = 02
unknown_objectclass = 03.
IF sy-subrc = 0.
DELETE FROM tpara WHERE paramid = lv_paramid.
DELETE FROM tparat WHERE paramid = lv_paramid.
IF sy-subrc = 0.
CALL FUNCTION 'RS_TREE_OBJECT_PLACEMENT'
EXPORTING
object = lv_paramid
operation = 'DELETE'
type = 'CR'.
ENDIF.
ELSE.
zcx_abapgit_exception=>raise( 'error from RS_PRAMETER_DELETE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'PARA'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_nrob IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lv_objectid TYPE cdhdr-objectid,
lt_cdhdr TYPE cdhdr_tab.
FIELD-SYMBOLS: <ls_cdhdr> LIKE LINE OF lt_cdhdr.
lv_objectid = ms_item-obj_name.
CALL FUNCTION 'CHANGEDOCUMENT_READ_HEADERS'
EXPORTING
objectclass = 'NRKROBJ'
objectid = lv_objectid
TABLES
i_cdhdr = lt_cdhdr
EXCEPTIONS
no_position_found = 1
wrong_access_to_archive = 2
time_zone_conversion_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
RETURN.
ENDIF.
SORT lt_cdhdr BY udate DESCENDING utime DESCENDING.
READ TABLE lt_cdhdr INDEX 1 ASSIGNING <ls_cdhdr>.
ASSERT sy-subrc = 0.
rv_user = <ls_cdhdr>-username.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-late_deser = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_object TYPE tnro-object.
SELECT SINGLE object FROM tnro INTO lv_object
WHERE object = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_object TYPE tnro-object,
ls_attributes TYPE tnro,
ls_text TYPE tnrot.
lv_object = ms_item-obj_name.
CALL FUNCTION 'NUMBER_RANGE_OBJECT_READ'
EXPORTING
language = mv_language
object = lv_object
IMPORTING
object_attributes = ls_attributes
object_text = ls_text
EXCEPTIONS
object_not_found = 1
OTHERS = 2.
IF sy-subrc = 1.
RETURN.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from NUMBER_RANGE_OBJECT_READ' ).
ENDIF.
io_xml->add( iv_name = 'ATTRIBUTES'
ig_data = ls_attributes ).
io_xml->add( iv_name = 'TEXT'
ig_data = ls_text ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lt_errors TYPE TABLE OF inoer,
ls_attributes TYPE tnro,
ls_text TYPE tnrot.
io_xml->read( EXPORTING iv_name = 'ATTRIBUTES'
CHANGING cg_data = ls_attributes ).
io_xml->read( EXPORTING iv_name = 'TEXT'
CHANGING cg_data = ls_text ).
CALL FUNCTION 'NUMBER_RANGE_OBJECT_UPDATE'
EXPORTING
indicator = 'I'
object_attributes = ls_attributes
object_text = ls_text
TABLES
errors = lt_errors
EXCEPTIONS
object_already_exists = 1
object_attributes_missing = 2
object_not_found = 3
object_text_missing = 4
wrong_indicator = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from NUMBER_RANGE_OBJECT_UPDATE' ).
ENDIF.
CALL FUNCTION 'NUMBER_RANGE_OBJECT_CLOSE'
EXPORTING
object = ls_attributes-object
EXCEPTIONS
object_not_initialized = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from NUMBER_RANGE_OBJECT_CLOSE' ).
ENDIF.
tadir_insert( iv_package ).
ENDMETHOD.
METHOD delete_intervals.
DATA: lv_error TYPE c LENGTH 1,
ls_error TYPE inrer,
lt_list TYPE STANDARD TABLE OF inriv WITH DEFAULT KEY,
lt_error_iv TYPE STANDARD TABLE OF inriv WITH DEFAULT KEY.
FIELD-SYMBOLS: <ls_list> LIKE LINE OF lt_list.
CALL FUNCTION 'NUMBER_RANGE_INTERVAL_LIST'
EXPORTING
object = iv_object
TABLES
interval = lt_list
EXCEPTIONS
nr_range_nr1_not_found = 1
nr_range_nr1_not_intern = 2
nr_range_nr2_must_be_space = 3
nr_range_nr2_not_extern = 4
nr_range_nr2_not_found = 5
object_not_found = 6
subobject_must_be_space = 7
subobject_not_found = 8
OTHERS = 9.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from NUMBER_RANGE_INTERVAL_LIST' ).
ENDIF.
IF lines( lt_list ) = 0.
RETURN.
ENDIF.
LOOP AT lt_list ASSIGNING <ls_list>.
CLEAR <ls_list>-nrlevel.
<ls_list>-procind = 'D'.
ENDLOOP.
CALL FUNCTION 'NUMBER_RANGE_INTERVAL_UPDATE'
EXPORTING
object = iv_object
IMPORTING
error = ls_error
error_occured = lv_error
TABLES
error_iv = lt_error_iv
interval = lt_list
EXCEPTIONS
object_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0 OR lv_error = abap_true.
zcx_abapgit_exception=>raise( 'error from NUMBER_RANGE_INTERVAL_UPDATE' ).
ENDIF.
CALL FUNCTION 'NUMBER_RANGE_UPDATE_CLOSE'
EXPORTING
object = iv_object
EXCEPTIONS
no_changes_made = 1
object_not_initialized = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from NUMBER_RANGE_UPDATE_CLOSE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_object TYPE tnro-object.
lv_object = ms_item-obj_name.
delete_intervals( lv_object ).
CALL FUNCTION 'NUMBER_RANGE_OBJECT_DELETE'
EXPORTING
language = mv_language
object = lv_object
EXCEPTIONS
delete_not_allowed = 1
object_not_found = 2
wrong_indicator = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from NUMBER_RANGE_OBJECT_DELETE' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
ls_bcdata-program = 'SAPMSNRO'.
ls_bcdata-dynpro = '0150'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'NRIV-OBJECT'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=DISP'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SNRO'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, NROB' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_msag IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE lastuser FROM t100a INTO rv_user
WHERE arbgb = ms_item-obj_name. "#EC CI_GENBUFF
IF sy-subrc <> 0 OR rv_user = ''.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_arbgb TYPE t100a-arbgb.
SELECT SINGLE arbgb FROM t100a INTO lv_arbgb
WHERE arbgb = ms_item-obj_name. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'MSAG'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
CALL FUNCTION 'RS_DELETE_MESSAGE_ID'
EXPORTING
nachrichtenklasse = ms_item-obj_name
EXCEPTIONS
not_executed = 1
not_found = 2
no_permission = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RS_DELETE_MESSAGE_ID' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_t100a TYPE t100a,
ls_t100t TYPE t100t,
ls_t100u TYPE t100u,
lt_t100 TYPE TABLE OF t100,
lt_before TYPE TABLE OF t100u.
FIELD-SYMBOLS: <ls_t100> LIKE LINE OF lt_t100.
io_xml->read( EXPORTING iv_name = 'T100A'
CHANGING cg_data = ls_t100a ).
io_xml->read( EXPORTING iv_name = 'T100'
CHANGING cg_data = lt_t100 ).
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
global_lock = abap_true
devclass = iv_package
object = ls_t100a-arbgb
object_class = 'T100'
mode = 'INSERT'
EXCEPTIONS
cancelled = 01
permission_failure = 02
unknown_objectclass = 03.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RS_CORR_INSERT' ).
ENDIF.
SELECT * FROM t100u INTO TABLE lt_before
WHERE arbgb = ls_t100a-arbgb ORDER BY msgnr. "#EC CI_GENBUFF "#EC CI_BYPASS
LOOP AT lt_t100 ASSIGNING <ls_t100>.
DELETE lt_before WHERE msgnr = <ls_t100>-msgnr.
MODIFY t100 FROM <ls_t100>. "#EC CI_SUBRC
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'MSAG: Table T100 modify failed' ).
ENDIF.
CLEAR ls_t100u.
MOVE-CORRESPONDING <ls_t100> TO ls_t100u ##enh_ok.
ls_t100u-name = sy-uname.
ls_t100u-datum = sy-datum.
ls_t100u-selfdef = '3'.
MODIFY t100u FROM ls_t100u. "#EC CI_SUBRC
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'MSAG: Table T100U modify failed' ).
ENDIF.
ENDLOOP.
ls_t100a-masterlang = mv_language.
ls_t100a-lastuser = sy-uname.
ls_t100a-respuser = sy-uname.
ls_t100a-ldate = sy-datum.
ls_t100a-ltime = sy-uzeit.
MODIFY t100a FROM ls_t100a. "#EC CI_SUBRC
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'MSAG: Table T100A modify failed' ).
ENDIF.
ls_t100t-sprsl = mv_language.
ls_t100t-arbgb = ls_t100a-arbgb.
ls_t100t-stext = ls_t100a-stext.
MODIFY t100t FROM ls_t100t. "#EC CI_SUBRC
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'MSAG: Table T100T modify failed' ).
ENDIF.
LOOP AT lt_before INTO ls_t100u.
DELETE FROM t100 WHERE arbgb = ls_t100u-arbgb
AND msgnr = ls_t100u-msgnr. "#EC CI_SUBRC
DELETE FROM t100u WHERE arbgb = ls_t100u-arbgb
AND msgnr = ls_t100u-msgnr. "#EC CI_SUBRC
ENDLOOP.
deserialize_texts( io_xml = io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_msg_id TYPE rglif-message_id,
ls_inf TYPE t100a,
lt_source TYPE TABLE OF t100.
lv_msg_id = ms_item-obj_name.
SELECT SINGLE * FROM t100a INTO ls_inf
WHERE arbgb = lv_msg_id. "#EC CI_GENBUFF
IF sy-subrc <> 0.
RETURN.
ENDIF.
CLEAR ls_inf-respuser.
SELECT * FROM t100 INTO TABLE lt_source
WHERE sprsl = mv_language
AND arbgb = lv_msg_id
ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF
CLEAR: ls_inf-lastuser,
ls_inf-ldate,
ls_inf-ltime.
io_xml->add( iv_name = 'T100A'
ig_data = ls_inf ).
io_xml->add( ig_data = lt_source
iv_name = 'T100' ).
serialize_texts( io_xml ).
ENDMETHOD.
METHOD serialize_texts.
DATA: lv_msg_id TYPE rglif-message_id,
lt_t100_texts TYPE tt_t100_texts,
lt_t100t TYPE TABLE OF t100t,
lt_i18n_langs TYPE TABLE OF langu.
lv_msg_id = ms_item-obj_name.
" Collect additional languages
" Skip master lang - it has been already serialized
SELECT DISTINCT sprsl AS langu INTO TABLE lt_i18n_langs
FROM t100t
WHERE arbgb = lv_msg_id
AND sprsl <> mv_language. "#EC CI_BYPASS "#EC CI_GENBUFF.
SORT lt_i18n_langs ASCENDING.
IF lines( lt_i18n_langs ) > 0.
SELECT * FROM t100t INTO CORRESPONDING FIELDS OF TABLE lt_t100t
WHERE sprsl <> mv_language
AND arbgb = lv_msg_id. "#EC CI_GENBUFF
SELECT * FROM t100 INTO CORRESPONDING FIELDS OF TABLE lt_t100_texts
FOR ALL ENTRIES IN lt_i18n_langs
WHERE sprsl = lt_i18n_langs-table_line
AND arbgb = lv_msg_id
ORDER BY PRIMARY KEY. "#EC CI_SUBRC "#EC CI_GENBUFF
SORT lt_t100t BY sprsl ASCENDING.
SORT lt_t100_texts BY sprsl msgnr ASCENDING.
io_xml->add( iv_name = 'I18N_LANGS'
ig_data = lt_i18n_langs ).
io_xml->add( iv_name = 'T100T'
ig_data = lt_t100t ).
io_xml->add( iv_name = 'T100_TEXTS'
ig_data = lt_t100_texts ).
ENDIF.
ENDMETHOD.
METHOD deserialize_texts.
DATA: lv_msg_id TYPE rglif-message_id,
ls_t100 TYPE t100,
lt_t100t TYPE TABLE OF t100t,
lt_t100_texts TYPE tt_t100_texts,
lt_t100u TYPE TABLE OF t100u.
FIELD-SYMBOLS: <ls_t100_text> TYPE ty_t100_texts.
lv_msg_id = ms_item-obj_name.
SELECT * FROM t100u INTO TABLE lt_t100u
WHERE arbgb = lv_msg_id ORDER BY PRIMARY KEY. "#EC CI_GENBUFF
io_xml->read( EXPORTING iv_name = 'T100_TEXTS'
CHANGING cg_data = lt_t100_texts ).
io_xml->read( EXPORTING iv_name = 'T100T'
CHANGING cg_data = lt_t100t ).
MODIFY t100t FROM TABLE lt_t100t. "#EC CI_SUBRC
LOOP AT lt_t100_texts ASSIGNING <ls_t100_text>.
"check if message exists
READ TABLE lt_t100u TRANSPORTING NO FIELDS
WITH KEY arbgb = lv_msg_id msgnr = <ls_t100_text>-msgnr BINARY SEARCH.
CHECK sy-subrc = 0. "if original message doesn't exist no translations added
MOVE-CORRESPONDING <ls_t100_text> TO ls_t100.
ls_t100-arbgb = lv_msg_id.
MODIFY t100 FROM ls_t100. "#EC CI_SUBRC
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'MSAG: Table T100 modify failed' ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_JOBD IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_job_definition TYPE REF TO object,
lv_name TYPE c LENGTH 32.
lv_name = ms_item-obj_name.
TRY.
CREATE OBJECT lo_job_definition TYPE ('CL_JR_JOB_DEFINITION')
EXPORTING
im_jd_name = lv_name.
CALL METHOD lo_job_definition->('DELETE_JD').
CATCH cx_root.
zcx_abapgit_exception=>raise( |Error deleting JOBD| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lr_job_definition TYPE REF TO data,
lo_job_definition TYPE REF TO object,
lv_name TYPE ty_jd_name.
FIELD-SYMBOLS: <lg_job_definition> TYPE any,
<lg_field> TYPE any.
lv_name = ms_item-obj_name.
TRY.
CREATE DATA lr_job_definition TYPE ('CL_JR_JOB_DEFINITION=>TY_JOB_DEFINITION').
ASSIGN lr_job_definition->* TO <lg_job_definition>.
ASSERT sy-subrc = 0.
io_xml->read(
EXPORTING
iv_name = 'JOBD'
CHANGING
cg_data = <lg_job_definition> ).
CREATE OBJECT lo_job_definition TYPE ('CL_JR_JOB_DEFINITION')
EXPORTING
im_jd_name = lv_name.
ASSIGN COMPONENT 'JDPACKAGE' OF STRUCTURE <lg_job_definition> TO <lg_field>.
<lg_field> = iv_package.
CALL METHOD lo_job_definition->('CREATE_JD')
EXPORTING
im_jd_attributes = <lg_job_definition>.
CATCH cx_root.
zcx_abapgit_exception=>raise( |Error deserializing JOBD| ).
ENDTRY.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_name TYPE ty_jd_name.
lv_name = ms_item-obj_name.
TRY.
CALL METHOD ('CL_JR_JD_MANAGER')=>('CHECK_JD_EXISTENCE')
EXPORTING
im_jd_name = lv_name
IMPORTING
ex_is_existing = rv_bool.
CATCH cx_root.
zcx_abapgit_exception=>raise( |JOBD not supported| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lv_obj_name TYPE e071-obj_name.
lv_obj_name = ms_item-obj_name.
CALL FUNCTION 'TR_OBJECT_JUMP_TO_TOOL'
EXPORTING
iv_pgmid = 'R3TR'
iv_object = ms_item-obj_type
iv_obj_name = lv_obj_name
iv_action = 'SHOW'
EXCEPTIONS
jump_not_possible = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from TR_OBJECT_JUMP_TO_TOOL, JOBD| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lr_job_definition TYPE REF TO data,
lo_job_definition TYPE REF TO object,
lv_name TYPE ty_jd_name.
FIELD-SYMBOLS: <lg_job_definition> TYPE any,
<lg_field> TYPE any.
lv_name = ms_item-obj_name.
TRY.
CREATE DATA lr_job_definition TYPE ('CL_JR_JOB_DEFINITION=>TY_JOB_DEFINITION').
ASSIGN lr_job_definition->* TO <lg_job_definition>.
ASSERT sy-subrc = 0.
CREATE OBJECT lo_job_definition TYPE ('CL_JR_JOB_DEFINITION')
EXPORTING
im_jd_name = lv_name.
CALL METHOD lo_job_definition->('GET_JD_ATTRIBUTES')
IMPORTING
ex_jd_attributes = <lg_job_definition>.
ASSIGN COMPONENT 'JDPACKAGE' OF STRUCTURE <lg_job_definition> TO <lg_field>.
CLEAR <lg_field>.
ASSIGN COMPONENT 'BTCJOB_USER' OF STRUCTURE <lg_job_definition> TO <lg_field>.
CLEAR <lg_field>.
ASSIGN COMPONENT 'OWNER' OF STRUCTURE <lg_job_definition> TO <lg_field>.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CREATED_DATE' OF STRUCTURE <lg_job_definition> TO <lg_field>.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CREATED_TIME' OF STRUCTURE <lg_job_definition> TO <lg_field>.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CHANGED_DATE' OF STRUCTURE <lg_job_definition> TO <lg_field>.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CHANGED_TIME' OF STRUCTURE <lg_job_definition> TO <lg_field>.
CLEAR <lg_field>.
io_xml->add( iv_name = 'JOBD'
ig_data = <lg_job_definition> ).
CATCH cx_root.
zcx_abapgit_exception=>raise( |Error serializing JOBD| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_INTF IMPLEMENTATION.
METHOD constructor.
super->constructor(
is_item = is_item
iv_language = iv_language ).
mi_object_oriented_object_fct = zcl_abapgit_oo_factory=>make( ms_item-obj_type ).
ENDMETHOD.
METHOD deserialize_abap.
DATA: ls_vseointerf TYPE vseointerf,
lt_source TYPE seop_source_string,
lt_descriptions TYPE zif_abapgit_definitions=>ty_seocompotx_tt,
ls_clskey TYPE seoclskey.
ls_clskey-clsname = ms_item-obj_name.
lt_source = mo_files->read_abap( ).
io_xml->read( EXPORTING iv_name = 'VSEOINTERF'
CHANGING cg_data = ls_vseointerf ).
mi_object_oriented_object_fct->create(
EXPORTING
iv_package = iv_package
CHANGING
cg_properties = ls_vseointerf ).
mi_object_oriented_object_fct->deserialize_source(
is_key = ls_clskey
it_source = lt_source ).
io_xml->read( EXPORTING iv_name = 'DESCRIPTIONS'
CHANGING cg_data = lt_descriptions ).
mi_object_oriented_object_fct->update_descriptions(
is_key = ls_clskey
it_descriptions = lt_descriptions ).
mi_object_oriented_object_fct->add_to_activation_list( ms_item ).
ENDMETHOD.
METHOD deserialize_docu.
DATA: lt_lines TYPE tlinetab,
lv_object TYPE dokhl-object.
io_xml->read( EXPORTING iv_name = 'LINES'
CHANGING cg_data = lt_lines ).
IF lines( lt_lines ) = 0.
RETURN.
ENDIF.
lv_object = ms_item-obj_name.
mi_object_oriented_object_fct->create_documentation(
it_lines = lt_lines
iv_object_name = lv_object
iv_language = mv_language ).
ENDMETHOD.
METHOD serialize_xml.
DATA:
lt_descriptions TYPE zif_abapgit_definitions=>ty_seocompotx_tt,
ls_vseointerf TYPE vseointerf,
ls_clskey TYPE seoclskey,
lt_lines TYPE tlinetab.
ls_clskey-clsname = ms_item-obj_name.
ls_vseointerf = mi_object_oriented_object_fct->get_interface_properties( ls_clskey ).
CLEAR: ls_vseointerf-uuid,
ls_vseointerf-author,
ls_vseointerf-createdon,
ls_vseointerf-changedby,
ls_vseointerf-changedon,
ls_vseointerf-chgdanyby,
ls_vseointerf-chgdanyon,
ls_vseointerf-r3release.
io_xml->add( iv_name = 'VSEOINTERF'
ig_data = ls_vseointerf ).
lt_lines = mi_object_oriented_object_fct->read_documentation(
iv_class_name = ls_clskey-clsname
iv_language = mv_language ).
IF lines( lt_lines ) > 0.
io_xml->add( iv_name = 'LINES'
ig_data = lt_lines ).
ENDIF.
lt_descriptions = mi_object_oriented_object_fct->read_descriptions( ls_clskey-clsname ).
IF lines( lt_descriptions ) > 0.
io_xml->add( iv_name = 'DESCRIPTIONS'
ig_data = lt_descriptions ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
TYPES: BEGIN OF ty_includes,
programm TYPE programm,
END OF ty_includes.
TYPES: BEGIN OF ty_reposrc,
unam TYPE reposrc-unam,
udat TYPE reposrc-udat,
utime TYPE reposrc-utime,
END OF ty_reposrc.
DATA: lt_reposrc TYPE STANDARD TABLE OF ty_reposrc,
ls_reposrc LIKE LINE OF lt_reposrc,
lt_includes TYPE STANDARD TABLE OF ty_includes.
lt_includes = mi_object_oriented_object_fct->get_includes( ms_item-obj_name ).
ASSERT lines( lt_includes ) > 0.
SELECT unam udat utime FROM reposrc
INTO TABLE lt_reposrc
FOR ALL ENTRIES IN lt_includes
WHERE progname = lt_includes-programm
AND r3state = 'A'.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ELSE.
SORT lt_reposrc BY udat DESCENDING utime DESCENDING.
READ TABLE lt_reposrc INDEX 1 INTO ls_reposrc.
ASSERT sy-subrc = 0.
rv_user = ls_reposrc-unam.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_clskey TYPE seoclskey.
ls_clskey-clsname = ms_item-obj_name.
mi_object_oriented_object_fct->delete( ls_clskey ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
deserialize_abap( io_xml = io_xml
iv_package = iv_package ).
deserialize_docu( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_class_key TYPE seoclskey,
lv_category TYPE seoclassdf-category.
ls_class_key-clsname = ms_item-obj_name.
rv_bool = mi_object_oriented_object_fct->exists( ls_class_key ).
IF rv_bool = abap_true.
SELECT SINGLE category FROM seoclassdf INTO lv_category
WHERE clsname = ls_class_key-clsname
AND ( version = '1'
OR version = '0' ) ##warn_ok. "#EC CI_GENBUFF
IF sy-subrc = 0 AND lv_category = seoc_category_webdynpro_class.
rv_bool = abap_false.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA:
lv_program TYPE program,
lt_includes TYPE seoincl_t.
lt_includes = mi_object_oriented_object_fct->get_includes( ms_item-obj_name ).
READ TABLE lt_includes INDEX 1 INTO lv_program.
"lv_program = cl_oo_classname_service=>get_interfacepool_name( lv_clsname ).
rv_changed = check_prog_changed_since(
iv_program = lv_program
iv_timestamp = iv_timestamp
iv_skip_gui = abap_true ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'INTF'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lt_source TYPE seop_source_string,
ls_interface_key TYPE seoclskey.
ls_interface_key-clsname = ms_item-obj_name.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
CALL FUNCTION 'SEO_BUFFER_REFRESH'
EXPORTING
version = seoc_version_active
force = seox_true.
CALL FUNCTION 'SEO_BUFFER_REFRESH'
EXPORTING
version = seoc_version_inactive
force = seox_true.
lt_source = mi_object_oriented_object_fct->serialize_abap( ls_interface_key ).
mo_files->add_abap( lt_source ).
serialize_xml( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE eqegraarg.
lv_object = |{ ms_item-obj_name }|.
OVERLAY lv_object WITH '==============================P'.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESEOCLASS'
iv_argument = lv_object ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_iext IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_extension = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_attributes TYPE edi_iapi01.
CALL FUNCTION 'EXTTYPE_READ'
EXPORTING
pi_cimtyp = mv_extension
IMPORTING
pe_attributes = ls_attributes
EXCEPTIONS
object_not_found = 1
db_error = 2
no_authority = 3
OTHERS = 4.
rv_user = ls_attributes-plast.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
CALL FUNCTION 'EXTTYPE_DELETE'
EXPORTING
pi_cimtyp = mv_extension
EXCEPTIONS
object_not_found = 1
lock_error = 2
action_not_possible = 3
transport_error = 4
db_error = 5
no_authority = 6
OTHERS = 7.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_extension TYPE ty_extention,
ls_attributes TYPE edi_iapi05.
io_xml->read(
EXPORTING
iv_name = 'IEXT'
CHANGING
cg_data = ls_extension ).
MOVE-CORRESPONDING ls_extension-attributes TO ls_attributes.
CALL FUNCTION 'EXTTYPE_CREATE'
EXPORTING
pi_cimtyp = mv_extension
pi_devclass = iv_package
pi_attributes = ls_attributes
TABLES
pt_syntax = ls_extension-t_syntax
EXCEPTIONS
object_not_found = 1
object_exists = 2
action_not_possible = 3
syntax_error = 4
segment_error = 5
transport_error = 6
db_error = 7
no_authority = 8
OTHERS = 9.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
CALL FUNCTION 'EXTTYPE_READ'
EXPORTING
pi_cimtyp = mv_extension
EXCEPTIONS
object_not_found = 1
db_error = 2
no_authority = 3
OTHERS = 4.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lt_bdcdata TYPE TABLE OF bdcdata.
FIELD-SYMBOLS: <ls_bdcdata> LIKE LINE OF lt_bdcdata.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-program = 'SAPMSED5'.
<ls_bdcdata>-dynpro = '0010'.
<ls_bdcdata>-dynbegin = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'SED5STRUC-OBJECT'.
<ls_bdcdata>-fval = ms_item-obj_name.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'SED5STRUC-SELECT_EXT'.
<ls_bdcdata>-fval = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BDC_OKCODE'.
<ls_bdcdata>-fval = '=DISP'.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'WE30'
mode_val = 'E'
TABLES
using_tab = lt_bdcdata
EXCEPTIONS
system_failure = 1
communication_failure = 2
resource_failure = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_extension TYPE ty_extention.
CALL FUNCTION 'EXTTYPE_READ'
EXPORTING
pi_cimtyp = mv_extension
IMPORTING
pe_attributes = ls_extension-attributes
TABLES
pt_syntax = ls_extension-t_syntax
EXCEPTIONS
object_not_found = 1
db_error = 2
no_authority = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
CLEAR: ls_extension-attributes-devc,
ls_extension-attributes-plast,
ls_extension-attributes-credate,
ls_extension-attributes-cretime,
ls_extension-attributes-ldate,
ls_extension-attributes-ltime.
io_xml->add( iv_name = 'IEXT'
ig_data = ls_extension ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_IDOC IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_idoctyp = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_attributes TYPE edi_iapi01.
CALL FUNCTION 'IDOCTYPE_READ'
EXPORTING
pi_idoctyp = mv_idoctyp
IMPORTING
pe_attributes = ls_attributes
EXCEPTIONS
object_not_found = 1
db_error = 2
no_authority = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
rv_user = ls_attributes-plast.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
CALL FUNCTION 'IDOCTYPE_DELETE'
EXPORTING
pi_idoctyp = mv_idoctyp
EXCEPTIONS
object_not_found = 1
lock_error = 2
action_not_possible = 3
transport_error = 4
db_error = 5
no_authority = 6
OTHERS = 7.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_idoc TYPE ty_idoc,
ls_attributes TYPE edi_iapi05.
io_xml->read(
EXPORTING
iv_name = 'IDOC'
CHANGING
cg_data = ls_idoc ).
MOVE-CORRESPONDING ls_idoc-attributes TO ls_attributes.
CALL FUNCTION 'IDOCTYPE_CREATE'
EXPORTING
pi_idoctyp = mv_idoctyp
pi_devclass = iv_package
pi_attributes = ls_attributes
TABLES
pt_syntax = ls_idoc-t_syntax
EXCEPTIONS
object_not_found = 1
object_exists = 2
action_not_possible = 3
syntax_error = 4
segment_error = 5
transport_error = 6
db_error = 7
no_authority = 8
OTHERS = 9.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
CALL FUNCTION 'IDOCTYPE_READ'
EXPORTING
pi_idoctyp = mv_idoctyp
EXCEPTIONS
object_not_found = 1
db_error = 2
no_authority = 3
OTHERS = 4.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lt_bdcdata TYPE TABLE OF bdcdata.
FIELD-SYMBOLS: <ls_bdcdata> LIKE LINE OF lt_bdcdata.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-program = 'SAPMSED5'.
<ls_bdcdata>-dynpro = '0010'.
<ls_bdcdata>-dynbegin = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'SED5STRUC-OBJECT'.
<ls_bdcdata>-fval = ms_item-obj_name.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'SED5STRUC-SELECT_ORG'.
<ls_bdcdata>-fval = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BDC_OKCODE'.
<ls_bdcdata>-fval = '=DISP'.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'WE30'
mode_val = 'E'
TABLES
using_tab = lt_bdcdata
EXCEPTIONS
system_failure = 1
communication_failure = 2
resource_failure = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_idoc TYPE ty_idoc.
CALL FUNCTION 'IDOCTYPE_READ'
EXPORTING
pi_idoctyp = mv_idoctyp
IMPORTING
pe_attributes = ls_idoc-attributes
TABLES
pt_syntax = ls_idoc-t_syntax
EXCEPTIONS
object_not_found = 1
db_error = 2
no_authority = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
CLEAR: ls_idoc-attributes-devc,
ls_idoc-attributes-plast,
ls_idoc-attributes-credate,
ls_idoc-attributes-cretime,
ls_idoc-attributes-ldate,
ls_idoc-attributes-ltime.
io_xml->add( iv_name = 'IDOC'
ig_data = ls_idoc ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_iatu IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD read.
DATA: li_template TYPE REF TO if_w3_api_template,
lt_source TYPE w3htmltabtype,
ls_name TYPE iacikeyt.
ls_name = ms_item-obj_name.
cl_w3_api_template=>if_w3_api_template~load(
EXPORTING
p_template_name = ls_name
IMPORTING
p_template = li_template
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from w3api_template~load' ).
ENDIF.
li_template->get_attributes( IMPORTING p_attributes = es_attr ).
CLEAR: es_attr-chname,
es_attr-tdate,
es_attr-ttime,
es_attr-devclass.
li_template->get_source( IMPORTING p_source = lt_source ).
CONCATENATE LINES OF lt_source INTO ev_source RESPECTING BLANKS.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_attr TYPE w3tempattr,
lv_source TYPE string.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
read( IMPORTING es_attr = ls_attr
ev_source = lv_source ).
io_xml->add( iv_name = 'ATTR'
ig_data = ls_attr ).
mo_files->add_string( iv_ext = 'html'
iv_string = lv_source ) ##NO_TEXT.
ENDMETHOD.
METHOD save.
DATA: lt_source TYPE w3htmltabtype,
lv_source TYPE string,
li_template TYPE REF TO if_w3_api_template.
cl_w3_api_template=>if_w3_api_template~create_new(
EXPORTING p_template_data = is_attr
p_program_name = is_attr-programm
IMPORTING p_template = li_template ).
li_template->set_attributes( is_attr ).
lv_source = iv_source.
WHILE strlen( lv_source ) >= 255.
APPEND lv_source(255) TO lt_source.
lv_source = lv_source+255.
ENDWHILE.
IF NOT lv_source IS INITIAL.
APPEND lv_source TO lt_source.
ENDIF.
li_template->set_source( lt_source ).
li_template->if_w3_api_object~save( ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_attr TYPE w3tempattr,
lv_source TYPE string.
io_xml->read( EXPORTING iv_name = 'ATTR'
CHANGING cg_data = ls_attr ).
lv_source = mo_files->read_string( 'html' ) ##NO_TEXT.
ls_attr-devclass = iv_package.
save( is_attr = ls_attr
iv_source = lv_source ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: li_template TYPE REF TO if_w3_api_template,
ls_name TYPE iacikeyt.
ls_name = ms_item-obj_name.
cl_w3_api_template=>if_w3_api_template~load(
EXPORTING
p_template_name = ls_name
IMPORTING
p_template = li_template
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from if_w3_api_template~load' ).
ENDIF.
li_template->if_w3_api_object~set_changeable( abap_true ).
li_template->if_w3_api_object~delete( ).
li_template->if_w3_api_object~save( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_name TYPE iacikeyt.
ls_name = ms_item-obj_name.
cl_w3_api_template=>if_w3_api_template~load(
EXPORTING
p_template_name = ls_name
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc = 1.
rv_bool = abap_false.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from w3_api_template~load' ).
ELSE.
rv_bool = abap_true.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_iasp IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD read.
DATA: li_service TYPE REF TO if_w3_api_service,
lv_name TYPE itsappl.
lv_name = ms_item-obj_name.
cl_w3_api_service=>if_w3_api_service~load(
EXPORTING
p_service_name = lv_name
IMPORTING
p_service = li_service
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from w3api_service~load' ).
ENDIF.
li_service->get_attributes( IMPORTING p_attributes = es_attr ).
CLEAR: es_attr-chname,
es_attr-tdate,
es_attr-ttime,
es_attr-devclass.
li_service->get_parameters( IMPORTING p_parameters = et_parameters ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_attr TYPE w3servattr,
lt_parameters TYPE w3servpara_tabletype.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
read( IMPORTING es_attr = ls_attr
et_parameters = lt_parameters ).
io_xml->add( iv_name = 'ATTR'
ig_data = ls_attr ).
io_xml->add( iv_name = 'PARAMETERS'
ig_data = lt_parameters ).
ENDMETHOD.
METHOD save.
DATA: li_service TYPE REF TO if_w3_api_service.
cl_w3_api_service=>if_w3_api_service~create_new(
EXPORTING p_service_data = is_attr
IMPORTING p_service = li_service ).
li_service->set_attributes( is_attr ).
li_service->set_parameters( it_parameters ).
li_service->if_w3_api_object~save( ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_attr TYPE w3servattr,
lt_parameters TYPE w3servpara_tabletype.
io_xml->read( EXPORTING iv_name = 'ATTR'
CHANGING cg_data = ls_attr ).
io_xml->read( EXPORTING iv_name = 'PARAMETERS'
CHANGING cg_data = lt_parameters ).
ls_attr-devclass = iv_package.
save( is_attr = ls_attr
it_parameters = lt_parameters ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: li_service TYPE REF TO if_w3_api_service,
lv_name TYPE itsappl.
lv_name = ms_item-obj_name.
cl_w3_api_service=>if_w3_api_service~load(
EXPORTING
p_service_name = lv_name
IMPORTING
p_service = li_service
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from if_w3_api_service~load' ).
ENDIF.
li_service->if_w3_api_object~set_changeable( abap_true ).
li_service->if_w3_api_object~delete( ).
li_service->if_w3_api_object~save( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_name TYPE itsappl.
lv_name = ms_item-obj_name.
cl_w3_api_service=>if_w3_api_service~load(
EXPORTING
p_service_name = lv_name
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc = 1.
rv_bool = abap_false.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from w3_api_service~load' ).
ELSE.
rv_bool = abap_true.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_iarp IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD read.
DATA: li_resource TYPE REF TO if_w3_api_resource,
ls_name TYPE w3resokey.
ls_name = ms_item-obj_name.
cl_w3_api_resource=>if_w3_api_resource~load(
EXPORTING
p_resource_name = ls_name
IMPORTING
p_resource = li_resource
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from w3api_resource~load' ).
ENDIF.
li_resource->get_attributes( IMPORTING p_attributes = es_attr ).
CLEAR: es_attr-chname,
es_attr-tdate,
es_attr-ttime,
es_attr-devclass.
li_resource->get_parameters( IMPORTING p_parameters = et_parameters ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_attr TYPE w3resoattr,
lt_parameters TYPE w3resopara_tabletype.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
read( IMPORTING es_attr = ls_attr
et_parameters = lt_parameters ).
io_xml->add( iv_name = 'ATTR'
ig_data = ls_attr ).
io_xml->add( iv_name = 'PARAMETERS'
ig_data = lt_parameters ).
ENDMETHOD.
METHOD save.
DATA: li_resource TYPE REF TO if_w3_api_resource.
cl_w3_api_resource=>if_w3_api_resource~create_new(
EXPORTING p_resource_data = is_attr
IMPORTING p_resource = li_resource ).
li_resource->set_attributes( is_attr ).
li_resource->set_parameters( it_parameters ).
li_resource->if_w3_api_object~save( ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_attr TYPE w3resoattr,
lt_parameters TYPE w3resopara_tabletype.
io_xml->read( EXPORTING iv_name = 'ATTR'
CHANGING cg_data = ls_attr ).
io_xml->read( EXPORTING iv_name = 'PARAMETERS'
CHANGING cg_data = lt_parameters ).
ls_attr-devclass = iv_package.
save( is_attr = ls_attr
it_parameters = lt_parameters ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: li_resource TYPE REF TO if_w3_api_resource,
ls_name TYPE w3resokey.
ls_name = ms_item-obj_name.
cl_w3_api_resource=>if_w3_api_resource~load(
EXPORTING
p_resource_name = ls_name
IMPORTING
p_resource = li_resource
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from if_w3_api_resource~load' ).
ENDIF.
li_resource->if_w3_api_object~set_changeable( abap_true ).
li_resource->if_w3_api_object~delete( ).
li_resource->if_w3_api_object~save( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_name TYPE w3resokey.
ls_name = ms_item-obj_name.
cl_w3_api_resource=>if_w3_api_resource~load(
EXPORTING
p_resource_name = ls_name
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc = 1.
rv_bool = abap_false.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from w3_api_resource~load' ).
ELSE.
rv_bool = abap_true.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_iamu IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_internet_appl_comp_binary TYPE ty_internet_appl_comp_binary.
ls_internet_appl_comp_binary = read( ).
io_xml->add( iv_name = 'IAMU'
ig_data = ls_internet_appl_comp_binary ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_internet_appl_comp_binary TYPE ty_internet_appl_comp_binary.
io_xml->read(
EXPORTING
iv_name = 'IAMU'
CHANGING
cg_data = ls_internet_appl_comp_binary ).
ls_internet_appl_comp_binary-attributes-devclass = iv_package.
save( ls_internet_appl_comp_binary ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
load_mime_api( ).
mo_mime_api->if_w3_api_object~set_changeable(
EXPORTING
p_changeable = abap_true
EXCEPTIONS
action_cancelled = 1
object_locked_by_other_user = 2
permission_failure = 3
object_already_changeable = 4
object_already_unlocked = 5
object_just_created = 6
object_deleted = 7
object_modified = 8
object_not_existing = 9
object_invalid = 10
error_occured = 11
OTHERS = 12 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~set_changeable| ).
ENDIF.
mo_mime_api->if_w3_api_object~delete(
EXCEPTIONS
object_not_empty = 1
object_not_changeable = 2
object_invalid = 3
error_occured = 4
OTHERS = 5 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~delete| ).
ENDIF.
mo_mime_api->if_w3_api_object~save(
EXCEPTIONS
object_invalid = 1
object_not_changeable = 2
action_cancelled = 3
permission_failure = 4
not_changed = 5
data_invalid = 6
error_occured = 7
OTHERS = 8 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~save| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_mime_name TYPE iacikeym.
ls_mime_name = ms_item-obj_name.
cl_w3_api_mime=>s_check_exist(
EXPORTING
p_mime_name = ls_mime_name
IMPORTING
p_exists = rv_bool ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD load_mime_api.
DATA: ls_mime_name TYPE iacikeym.
ls_mime_name = ms_item-obj_name.
cl_w3_api_mime=>if_w3_api_mime~load(
EXPORTING
p_mime_name = ls_mime_name
IMPORTING
p_mime = mo_mime_api
EXCEPTIONS
object_not_existing = 1
permission_failure = 2
data_corrupt = 3
error_occured = 4
OTHERS = 6 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from if_w3_api_mime~load' ).
ENDIF.
ENDMETHOD.
METHOD read.
load_mime_api( ).
mo_mime_api->get_attributes(
IMPORTING
p_attributes = rs_internet_appl_comp_binary-attributes
EXCEPTIONS
object_invalid = 1
mime_deleted = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~get_attributes| ).
ENDIF.
CLEAR: rs_internet_appl_comp_binary-attributes-chname,
rs_internet_appl_comp_binary-attributes-tdate,
rs_internet_appl_comp_binary-attributes-ttime,
rs_internet_appl_comp_binary-attributes-devclass.
mo_mime_api->get_source(
IMPORTING
p_source = rs_internet_appl_comp_binary-source
p_datalength = rs_internet_appl_comp_binary-length
EXCEPTIONS
object_invalid = 1
mime_deleted = 2
error_occured = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~get_source| ).
ENDIF.
ENDMETHOD.
METHOD save.
cl_w3_api_mime=>if_w3_api_mime~create_new(
EXPORTING
p_mime_data = is_internet_appl_comp_binary-attributes
p_mime_content = is_internet_appl_comp_binary-source
p_datalength = is_internet_appl_comp_binary-length
IMPORTING
p_mime = mo_mime_api
EXCEPTIONS
object_already_existing = 1
object_just_created = 2
not_authorized = 3
undefined_name = 4
author_not_existing = 5
action_cancelled = 6
error_occured = 7
OTHERS = 8 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~create_ne| ).
ENDIF.
mo_mime_api->if_w3_api_object~save(
EXCEPTIONS
object_invalid = 1
object_not_changeable = 2
action_cancelled = 3
permission_failure = 4
not_changed = 5
data_invalid = 6
error_occured = 7
OTHERS = 8 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~save| ).
ENDIF.
release_lock( ).
ENDMETHOD.
METHOD release_lock.
" As a side effect this method removes also existing locks
mo_mime_api->if_w3_api_object~set_changeable(
EXPORTING
p_changeable = abap_false
EXCEPTIONS
action_cancelled = 1
object_locked_by_other_user = 2
permission_failure = 3
object_already_changeable = 4
object_already_unlocked = 5
object_just_created = 6
object_deleted = 7
object_modified = 8
object_not_existing = 9
object_invalid = 10
error_occured = 11
OTHERS = 12 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from if_w3_api_mime~set_changeable| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_FUGR IMPLEMENTATION.
METHOD are_exceptions_class_based.
DATA:
lt_dokumentation TYPE TABLE OF funct,
lt_exception_list TYPE TABLE OF rsexc,
lt_export_parameter TYPE TABLE OF rsexp,
lt_import_parameter TYPE TABLE OF rsimp,
lt_tables_parameter TYPE TABLE OF rstbl.
CALL FUNCTION 'FUNCTION_IMPORT_DOKU'
EXPORTING
funcname = iv_function_name
IMPORTING
exception_class = rv_return
TABLES
dokumentation = lt_dokumentation
exception_list = lt_exception_list
export_parameter = lt_export_parameter
import_parameter = lt_import_parameter
tables_parameter = lt_tables_parameter
EXCEPTIONS
error_message = 1
function_not_found = 2
invalid_name = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from FUNCTION_IMPORT_DOKU' ).
ENDIF.
ENDMETHOD.
METHOD deserialize_functions.
DATA: lv_include TYPE rs38l-include,
lv_area TYPE rs38l-area,
lv_group TYPE rs38l-area,
lv_namespace TYPE rs38l-namespace,
lt_source TYPE TABLE OF abaptxt255.
FIELD-SYMBOLS: <ls_func> LIKE LINE OF it_functions.
LOOP AT it_functions ASSIGNING <ls_func>.
lt_source = mo_files->read_abap( iv_extra = <ls_func>-funcname ).
lv_area = ms_item-obj_name.
CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT'
EXPORTING
complete_area = lv_area
IMPORTING
namespace = lv_namespace
group = lv_group
EXCEPTIONS
OTHERS = 12.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from FUNCTION_INCLUDE_SPLIT' ).
ENDIF.
CALL FUNCTION 'FUNCTION_EXISTS'
EXPORTING
funcname = <ls_func>-funcname
IMPORTING
include = lv_include
EXCEPTIONS
function_not_exist = 1.
IF sy-subrc = 0.
CALL FUNCTION 'FUNCTION_DELETE'
EXPORTING
funcname = <ls_func>-funcname
suppress_success_message = abap_true
EXCEPTIONS
error_message = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from FUNCTION_DELETE' ).
ENDIF.
ENDIF.
CALL FUNCTION 'RS_FUNCTIONMODULE_INSERT'
EXPORTING
funcname = <ls_func>-funcname
function_pool = lv_group
interface_global = <ls_func>-global_flag
remote_call = <ls_func>-remote_call
short_text = <ls_func>-short_text
update_task = <ls_func>-update_task
exception_class = <ls_func>-exception_classes
namespace = lv_namespace
remote_basxml_supported = <ls_func>-remote_basxml
IMPORTING
function_include = lv_include
TABLES
import_parameter = <ls_func>-import
export_parameter = <ls_func>-export
tables_parameter = <ls_func>-tables
changing_parameter = <ls_func>-changing
exception_list = <ls_func>-exception
parameter_docu = <ls_func>-documentation
EXCEPTIONS
double_task = 1
error_message = 2
function_already_exists = 3
invalid_function_pool = 4
invalid_name = 5
too_many_functions = 6
no_modify_permission = 7
no_show_permission = 8
enqueue_system_failure = 9
canceled_in_corr = 10
OTHERS = 11.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |error from RS_FUNCTIONMODULE_INSERT: {
sy-subrc } { sy-msgid }{ sy-msgno }| ).
ENDIF.
INSERT REPORT lv_include FROM lt_source.
ENDLOOP.
ENDMETHOD.
METHOD deserialize_includes.
DATA: lo_xml TYPE REF TO zcl_abapgit_xml_input,
ls_progdir TYPE ty_progdir,
lt_includes TYPE rso_t_objnm,
lt_tpool TYPE textpool_table,
lt_tpool_ext TYPE zif_abapgit_definitions=>ty_tpool_tt,
lt_source TYPE TABLE OF abaptxt255.
FIELD-SYMBOLS: <lv_include> LIKE LINE OF lt_includes.
tadir_insert( iv_package ).
io_xml->read( EXPORTING iv_name = 'INCLUDES'
CHANGING cg_data = lt_includes ).
LOOP AT lt_includes ASSIGNING <lv_include>.
lt_source = mo_files->read_abap( iv_extra = <lv_include> ).
lo_xml = mo_files->read_xml( <lv_include> ).
lo_xml->read( EXPORTING iv_name = 'PROGDIR'
CHANGING cg_data = ls_progdir ).
lo_xml->read( EXPORTING iv_name = 'TPOOL'
CHANGING cg_data = lt_tpool_ext ).
lt_tpool = read_tpool( lt_tpool_ext ).
deserialize_program( is_progdir = ls_progdir
it_source = lt_source
it_tpool = lt_tpool
iv_package = iv_package ).
deserialize_textpool( iv_program = <lv_include>
it_tpool = lt_tpool
iv_is_include = abap_true ).
ENDLOOP.
ENDMETHOD.
METHOD deserialize_xml.
DATA: lv_complete TYPE rs38l-area,
lv_namespace TYPE rs38l-namespace,
lv_areat TYPE tlibt-areat,
lv_stext TYPE tftit-stext,
lv_group TYPE rs38l-area,
lv_abap_version TYPE trdir-uccheck.
lv_abap_version = get_abap_version( io_xml ).
lv_complete = ms_item-obj_name.
CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT'
EXPORTING
complete_area = lv_complete
IMPORTING
namespace = lv_namespace
group = lv_group
EXCEPTIONS
include_not_exists = 1
group_not_exists = 2
no_selections = 3
no_function_include = 4
no_function_pool = 5
delimiter_wrong_position = 6
no_customer_function_group = 7
no_customer_function_include = 8
reserved_name_customer = 9
namespace_too_long = 10
area_length_error = 11
OTHERS = 12.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from FUNCTION_INCLUDE_SPLIT' ).
ENDIF.
io_xml->read( EXPORTING iv_name = 'AREAT'
CHANGING cg_data = lv_areat ).
lv_stext = lv_areat.
CALL FUNCTION 'RS_FUNCTION_POOL_INSERT'
EXPORTING
function_pool = lv_group
short_text = lv_stext
namespace = lv_namespace
devclass = iv_package
unicode_checks = lv_abap_version
EXCEPTIONS
name_already_exists = 1
name_not_correct = 2
function_already_exists = 3
invalid_function_pool = 4
invalid_name = 5
too_many_functions = 6
no_modify_permission = 7
no_show_permission = 8
enqueue_system_failure = 9
canceled_in_corr = 10
undefined_error = 11
OTHERS = 12.
CASE sy-subrc.
WHEN 0.
" Everything is ok
WHEN 1 OR 3.
" If the function group exists we need to manually update the short text
update_func_group_short_text( iv_group = lv_group
iv_short_text = lv_stext ).
WHEN OTHERS.
zcx_abapgit_exception=>raise( |error from RS_FUNCTION_POOL_INSERT, code: { sy-subrc }| ).
ENDCASE.
ENDMETHOD.
METHOD functions.
DATA: lv_area TYPE rs38l-area.
lv_area = ms_item-obj_name.
CALL FUNCTION 'RS_FUNCTION_POOL_CONTENTS'
EXPORTING
function_pool = lv_area
TABLES
functab = rt_functab
EXCEPTIONS
function_pool_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RS_FUNCTION_POOL_CONTENTS' ).
ENDIF.
SORT rt_functab BY funcname ASCENDING.
DELETE ADJACENT DUPLICATES FROM rt_functab COMPARING funcname.
ENDMETHOD.
METHOD get_abap_version.
DATA: lt_includes TYPE rso_t_objnm,
ls_progdir TYPE ty_progdir,
lo_xml TYPE REF TO zcl_abapgit_xml_input.
FIELD-SYMBOLS: <lv_include> LIKE LINE OF lt_includes.
io_xml->read( EXPORTING iv_name = 'INCLUDES'
CHANGING cg_data = lt_includes ).
LOOP AT lt_includes ASSIGNING <lv_include>.
lo_xml = mo_files->read_xml( <lv_include> ).
lo_xml->read( EXPORTING iv_name = 'PROGDIR'
CHANGING cg_data = ls_progdir ).
IF ls_progdir-uccheck IS INITIAL.
CONTINUE.
ELSEIF rv_abap_version IS INITIAL.
rv_abap_version = ls_progdir-uccheck.
CONTINUE.
ELSEIF rv_abap_version NE ls_progdir-uccheck.
zcx_abapgit_exception=>raise( 'different ABAP Language Versions' ).
ENDIF.
ENDLOOP.
IF rv_abap_version IS INITIAL.
rv_abap_version = 'X'.
ENDIF.
ENDMETHOD.
METHOD includes.
TYPES: BEGIN OF ty_reposrc,
progname TYPE reposrc-progname,
cnam TYPE reposrc-cnam,
END OF ty_reposrc.
DATA: lt_reposrc TYPE STANDARD TABLE OF ty_reposrc WITH DEFAULT KEY,
ls_reposrc LIKE LINE OF lt_reposrc,
lv_program TYPE program,
lv_offset_ns TYPE i,
lv_tabix LIKE sy-tabix,
lt_functab TYPE ty_rs38l_incl_tt.
FIELD-SYMBOLS: <lv_include> LIKE LINE OF rt_includes,
<ls_func> LIKE LINE OF lt_functab.
lv_program = main_name( ).
lt_functab = functions( ).
CALL FUNCTION 'RS_GET_ALL_INCLUDES'
EXPORTING
program = lv_program
TABLES
includetab = rt_includes
EXCEPTIONS
not_existent = 1
no_program = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RS_GET_ALL_INCLUDES' ).
ENDIF.
LOOP AT lt_functab ASSIGNING <ls_func>.
DELETE TABLE rt_includes FROM <ls_func>-include.
ENDLOOP.
APPEND INITIAL LINE TO rt_includes ASSIGNING <lv_include>.
IF ms_item-obj_name(1) <> '/'.
"FGroup name does not contain a namespace
<lv_include> = |L{ ms_item-obj_name }T00|.
ELSE.
"FGroup name contains a namespace
lv_offset_ns = find( val = ms_item-obj_name+1 sub = '/' ).
lv_offset_ns = lv_offset_ns + 2.
<lv_include> = |{ ms_item-obj_name(lv_offset_ns) }L{ ms_item-obj_name+lv_offset_ns }T00|.
ENDIF.
IF lines( rt_includes ) > 0.
SELECT progname cnam FROM reposrc
INTO TABLE lt_reposrc
FOR ALL ENTRIES IN rt_includes
WHERE progname = rt_includes-table_line
AND r3state = 'A'.
SORT lt_reposrc BY progname ASCENDING.
ENDIF.
LOOP AT rt_includes ASSIGNING <lv_include>.
lv_tabix = sy-tabix.
READ TABLE lt_reposrc INTO ls_reposrc
WITH KEY progname = <lv_include> BINARY SEARCH.
IF sy-subrc <> 0 OR ls_reposrc-cnam = 'SAP'.
DELETE rt_includes INDEX lv_tabix.
ENDIF.
ENDLOOP.
APPEND lv_program TO rt_includes.
ENDMETHOD.
METHOD is_any_function_module_locked.
DATA: lt_functions TYPE zcl_abapgit_object_fugr=>ty_rs38l_incl_tt.
FIELD-SYMBOLS: <ls_function> TYPE rs38l_incl.
TRY.
lt_functions = functions( ).
CATCH zcx_abapgit_exception.
RETURN.
ENDTRY.
LOOP AT lt_functions ASSIGNING <ls_function>.
IF exists_a_lock_entry_for( iv_lock_object = 'ESFUNCTION'
iv_argument = |{ <ls_function>-funcname }| ) = abap_true.
rv_any_function_module_locked = abap_true.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD is_any_include_locked.
DATA: lt_includes TYPE rso_t_objnm.
FIELD-SYMBOLS: <lv_include> TYPE sobj_name.
TRY.
lt_includes = includes( ).
CATCH zcx_abapgit_exception.
RETURN.
ENDTRY.
LOOP AT lt_includes ASSIGNING <lv_include>.
IF exists_a_lock_entry_for( iv_lock_object = 'ESRDIRE'
iv_argument = |{ <lv_include> }| ) = abap_true.
rv_is_any_include_locked = abap_true.
EXIT.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD is_function_group_locked.
DATA: lv_object TYPE eqegraarg.
lv_object = |FG{ ms_item-obj_name }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_functions_group_locked = exists_a_lock_entry_for( iv_lock_object = 'EEUDB'
iv_argument = lv_object ).
ENDMETHOD.
METHOD main_name.
DATA: lv_area TYPE rs38l-area,
lv_namespace TYPE rs38l-namespace,
lv_group TYPE rs38l-area.
lv_area = ms_item-obj_name.
CALL FUNCTION 'FUNCTION_INCLUDE_SPLIT'
EXPORTING
complete_area = lv_area
IMPORTING
namespace = lv_namespace
group = lv_group
EXCEPTIONS
include_not_exists = 1
group_not_exists = 2
no_selections = 3
no_function_include = 4
no_function_pool = 5
delimiter_wrong_position = 6
no_customer_function_group = 7
no_customer_function_include = 8
reserved_name_customer = 9
namespace_too_long = 10
area_length_error = 11
OTHERS = 12.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from FUNCTION_INCLUDE_SPLIT' ).
ENDIF.
CONCATENATE lv_namespace 'SAPL' lv_group INTO rv_program.
ENDMETHOD.
METHOD serialize_functions.
DATA:
lt_source TYPE TABLE OF rssource,
lt_functab TYPE ty_rs38l_incl_tt,
lt_new_source TYPE rsfb_source,
ls_function LIKE LINE OF rt_functions.
FIELD-SYMBOLS: <ls_func> LIKE LINE OF lt_functab.
lt_functab = functions( ).
LOOP AT lt_functab ASSIGNING <ls_func>.
CLEAR ls_function.
MOVE-CORRESPONDING <ls_func> TO ls_function.
CLEAR lt_new_source.
CLEAR lt_source.
CALL FUNCTION 'RPY_FUNCTIONMODULE_READ_NEW'
EXPORTING
functionname = <ls_func>-funcname
IMPORTING
global_flag = ls_function-global_flag
remote_call = ls_function-remote_call
update_task = ls_function-update_task
short_text = ls_function-short_text
remote_basxml_supported = ls_function-remote_basxml
TABLES
import_parameter = ls_function-import
changing_parameter = ls_function-changing
export_parameter = ls_function-export
tables_parameter = ls_function-tables
exception_list = ls_function-exception
documentation = ls_function-documentation
source = lt_source
CHANGING
new_source = lt_new_source
EXCEPTIONS
error_message = 1
function_not_found = 2
invalid_name = 3
OTHERS = 4.
IF sy-subrc = 2.
CONTINUE.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RPY_FUNCTIONMODULE_READ_NEW' ).
ENDIF.
ls_function-exception_classes = are_exceptions_class_based( <ls_func>-funcname ).
APPEND ls_function TO rt_functions.
IF NOT lt_new_source IS INITIAL.
mo_files->add_abap( iv_extra = <ls_func>-funcname
it_abap = lt_new_source ).
ELSE.
mo_files->add_abap( iv_extra = <ls_func>-funcname
it_abap = lt_source ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD serialize_includes.
DATA: lt_includes TYPE rso_t_objnm.
FIELD-SYMBOLS: <lv_include> LIKE LINE OF lt_includes.
lt_includes = includes( ).
LOOP AT lt_includes ASSIGNING <lv_include>.
serialize_program( is_item = ms_item
io_files = mo_files
iv_program = <lv_include>
iv_extra = <lv_include> ).
ENDLOOP.
ENDMETHOD.
METHOD serialize_xml.
DATA: lt_includes TYPE rso_t_objnm,
lv_areat TYPE tlibt-areat.
SELECT SINGLE areat INTO lv_areat
FROM tlibt
WHERE spras = mv_language
AND area = ms_item-obj_name. "#EC CI_GENBUFF "#EC CI_SUBRC
lt_includes = includes( ).
io_xml->add( iv_name = 'AREAT'
ig_data = lv_areat ).
io_xml->add( iv_name = 'INCLUDES'
ig_data = lt_includes ).
ENDMETHOD.
METHOD update_func_group_short_text.
" We update the short text directly.
" SE80 does the same in
" Program SAPLSEUF / LSEUFF07
" FORM GROUP_CHANGE
UPDATE tlibt SET areat = iv_short_text
WHERE spras = sy-langu
AND area = iv_group.
ENDMETHOD.
METHOD update_where_used.
DATA: lv_include LIKE LINE OF it_includes,
lo_cross TYPE REF TO cl_wb_crossreference.
LOOP AT it_includes INTO lv_include.
CREATE OBJECT lo_cross
EXPORTING
p_name = lv_include
p_include = lv_include.
lo_cross->index_actualize( ).
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
TYPES: BEGIN OF ty_stamps,
user TYPE xubname,
date TYPE d,
time TYPE t,
END OF ty_stamps.
DATA: lt_stamps TYPE STANDARD TABLE OF ty_stamps WITH DEFAULT KEY,
lv_program TYPE program,
lt_includes TYPE rso_t_objnm.
FIELD-SYMBOLS: <ls_stamp> LIKE LINE OF lt_stamps,
<lv_include> LIKE LINE OF lt_includes.
lv_program = main_name( ).
CALL FUNCTION 'RS_GET_ALL_INCLUDES'
EXPORTING
program = lv_program
TABLES
includetab = lt_includes
EXCEPTIONS
not_existent = 1
no_program = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from RS_GET_ALL_INCLUDES' ).
ENDIF.
SELECT unam AS user udat AS date utime AS time FROM reposrc
APPENDING CORRESPONDING FIELDS OF TABLE lt_stamps
WHERE progname = lv_program
AND r3state = 'A'. "#EC CI_SUBRC
LOOP AT lt_includes ASSIGNING <lv_include>.
SELECT unam AS user udat AS date utime AS time FROM reposrc
APPENDING CORRESPONDING FIELDS OF TABLE lt_stamps
WHERE progname = <lv_include>
AND r3state = 'A'. "#EC CI_SUBRC
ENDLOOP.
SELECT unam AS user udat AS date utime AS time FROM repotext " Program text pool
APPENDING CORRESPONDING FIELDS OF TABLE lt_stamps
WHERE progname = lv_program
AND r3state = 'A'. "#EC CI_SUBRC
SELECT vautor AS user vdatum AS date vzeit AS time FROM eudb " GUI
APPENDING CORRESPONDING FIELDS OF TABLE lt_stamps
WHERE relid = 'CU'
AND name = lv_program
AND srtf2 = 0 ##TOO_MANY_ITAB_FIELDS.
SORT lt_stamps BY date DESCENDING time DESCENDING.
READ TABLE lt_stamps INDEX 1 ASSIGNING <ls_stamp>.
IF sy-subrc = 0.
rv_user = <ls_stamp>-user.
ELSE.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_area TYPE rs38l-area,
lt_includes TYPE rso_t_objnm.
lt_includes = includes( ).
lv_area = ms_item-obj_name.
CALL FUNCTION 'RS_FUNCTION_POOL_DELETE'
EXPORTING
area = lv_area
suppress_popups = abap_true
skip_progress_ind = abap_true
EXCEPTIONS
canceled_in_corr = 1
enqueue_system_failure = 2
function_exist = 3
not_executed = 4
no_modify_permission = 5
no_show_permission = 6
permission_failure = 7
pool_not_exist = 8
cancelled = 9
OTHERS = 10.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_FUNCTION_POOL_DELETE' ).
ENDIF.
update_where_used( lt_includes ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_program_name TYPE programm,
lt_functions TYPE ty_function_tt,
lt_dynpros TYPE ty_dynpro_tt,
ls_cua TYPE ty_cua.
deserialize_xml(
io_xml = io_xml
iv_package = iv_package ).
io_xml->read( EXPORTING iv_name = 'FUNCTIONS'
CHANGING cg_data = lt_functions ).
deserialize_functions( lt_functions ).
deserialize_includes(
io_xml = io_xml
iv_package = iv_package ).
lv_program_name = main_name( ).
io_xml->read( EXPORTING iv_name = 'DYNPROS'
CHANGING cg_data = lt_dynpros ).
deserialize_dynpros( it_dynpros = lt_dynpros ).
io_xml->read( EXPORTING iv_name = 'CUA'
CHANGING cg_data = ls_cua ).
deserialize_cua( iv_program_name = lv_program_name
is_cua = ls_cua ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_pool TYPE tlibg-area.
lv_pool = ms_item-obj_name.
CALL FUNCTION 'RS_FUNCTION_POOL_EXISTS'
EXPORTING
function_pool = lv_pool
EXCEPTIONS
pool_not_exists = 1.
rv_bool = boolc( sy-subrc <> 1 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA: lt_functab TYPE ty_rs38l_incl_tt,
lt_includes TYPE rso_t_objnm.
FIELD-SYMBOLS: <ls_func> LIKE LINE OF lt_functab,
<lv_include_name> LIKE LINE OF lt_includes.
lt_includes = includes( ). " Main prog also included here
LOOP AT lt_includes ASSIGNING <lv_include_name>.
rv_changed = check_prog_changed_since(
iv_program = <lv_include_name>
iv_timestamp = iv_timestamp ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
ENDLOOP.
lt_functab = functions( ).
LOOP AT lt_functab ASSIGNING <ls_func>.
rv_changed = check_prog_changed_since(
iv_program = <ls_func>-include
iv_timestamp = iv_timestamp ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_program TYPE program.
lv_program = main_name( ).
IF is_function_group_locked( ) = abap_true
OR is_any_include_locked( ) = abap_true
OR is_any_function_module_locked( ) = abap_true
OR is_any_dynpro_locked( lv_program ) = abap_true
OR is_cua_locked( lv_program ) = abap_true
OR is_text_locked( lv_program ) = abap_true.
rv_is_locked = abap_true.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'FUGR'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lt_functions TYPE ty_function_tt,
ls_progdir TYPE ty_progdir,
lv_program_name TYPE programm,
lt_dynpros TYPE ty_dynpro_tt,
ls_cua TYPE ty_cua.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
serialize_xml( io_xml ).
lt_functions = serialize_functions( ).
io_xml->add( iv_name = 'FUNCTIONS'
ig_data = lt_functions ).
serialize_includes( ).
lv_program_name = main_name( ).
ls_progdir = read_progdir( lv_program_name ).
IF ls_progdir-subc = 'F'.
lt_dynpros = serialize_dynpros( lv_program_name ).
io_xml->add( iv_name = 'DYNPROS'
ig_data = lt_dynpros ).
ls_cua = serialize_cua( lv_program_name ).
io_xml->add( iv_name = 'CUA'
ig_data = ls_cua ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_FORM IMPLEMENTATION.
METHOD build_extra_from_header.
DATA: lv_tdspras TYPE laiso.
CALL FUNCTION 'CONVERSION_EXIT_ISOLA_OUTPUT'
EXPORTING
input = is_header-tdspras
IMPORTING
output = lv_tdspras.
rv_result = c_objectname_tdlines && '_' && lv_tdspras.
ENDMETHOD.
METHOD build_extra_from_header_old.
rv_result = c_objectname_tdlines && '_' && is_header-tdspras.
ENDMETHOD.
METHOD compress_lines.
DATA lv_string TYPE string.
DATA lo_xml TYPE REF TO zcl_abapgit_xml_output.
CREATE OBJECT lo_xml.
lo_xml->add( iv_name = c_objectname_tdlines
ig_data = it_lines ).
lv_string = lo_xml->render( ).
IF lv_string IS NOT INITIAL.
mo_files->add_string( iv_extra =
build_extra_from_header( is_form_data-form_header )
iv_ext = c_extension_xml
iv_string = lv_string ).
ENDIF.
ENDMETHOD.
METHOD extract_tdlines.
DATA lv_string TYPE string.
DATA lo_xml TYPE REF TO zcl_abapgit_xml_input.
TRY.
lv_string = mo_files->read_string( iv_extra =
build_extra_from_header( is_form_data-form_header )
iv_ext = c_extension_xml ).
CATCH zcx_abapgit_exception.
lv_string = mo_files->read_string( iv_extra =
build_extra_from_header_old( is_form_data-form_header )
iv_ext = c_extension_xml ).
ENDTRY.
CREATE OBJECT lo_xml EXPORTING iv_xml = lv_string.
lo_xml->read( EXPORTING iv_name = c_objectname_tdlines
CHANGING cg_data = rt_lines ).
ENDMETHOD.
METHOD find_form.
DATA: lv_text_name TYPE thead-tdname.
lv_text_name = iv_object_name.
CALL FUNCTION 'SELECT_TEXT'
EXPORTING
database_only = abap_true
id = 'TXT'
language = '*'
name = lv_text_name
object = c_objectname_form
TABLES
selections = rt_text_header
EXCEPTIONS
OTHERS = 1 ##fm_subrc_ok ##NO_TEXT. "#EC CI_SUBRC
ENDMETHOD.
METHOD get_last_changes.
DATA: lv_form_name TYPE thead-tdform.
CLEAR rs_last_changed.
lv_form_name = iv_form_name.
CALL FUNCTION 'READ_FORM'
EXPORTING
form = lv_form_name
read_only_header = abap_true
IMPORTING
form_header = rs_last_changed.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_last_changed TYPE tys_form_header.
ls_last_changed = get_last_changes( ms_item-obj_name ).
IF ls_last_changed-tdluser IS NOT INITIAL.
rv_user = ls_last_changed-tdluser.
ELSE.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_name TYPE itcta-tdform.
lv_name = ms_item-obj_name.
CALL FUNCTION 'DELETE_FORM'
EXPORTING
form = lv_name
language = '*'.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lt_form_data TYPE tyt_form_data.
DATA: lt_lines TYPE tyt_lines.
FIELD-SYMBOLS: <ls_form_data> TYPE LINE OF tyt_form_data.
io_xml->read( EXPORTING iv_name = c_objectname_form
CHANGING cg_data = lt_form_data ).
LOOP AT lt_form_data ASSIGNING <ls_form_data>.
lt_lines = extract_tdlines( <ls_form_data> ).
_save_form( EXPORTING it_lines = lt_lines
CHANGING cs_form_data = <ls_form_data> ).
ENDLOOP.
CALL FUNCTION 'SAPSCRIPT_DELETE_LOAD'
EXPORTING
delete = abap_true
form = '*'
write = space.
tadir_insert( iv_package ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_form_name TYPE thead-tdform.
lv_form_name = ms_item-obj_name.
CALL FUNCTION 'READ_FORM'
EXPORTING
form = lv_form_name
read_only_header = abap_true
IMPORTING
found = rv_bool.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA: ls_last_changed TYPE tys_form_header.
DATA: lv_last_changed_ts TYPE timestamp.
ls_last_changed = get_last_changes( ms_item-obj_name ).
CONVERT DATE ls_last_changed-tdldate TIME ls_last_changed-tdltime
INTO TIME STAMP lv_last_changed_ts TIME ZONE sy-zonlo.
rv_changed = boolc( sy-subrc <> 0 OR lv_last_changed_ts > iv_timestamp ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE seqg3-garg.
" example lock entry
"'001FORM ZTEST_SAPSCRIPT TXT'
lv_object = |{ sy-mandt }{ ms_item-obj_type } { ms_item-obj_name }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESSFORM'
iv_argument = lv_object ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lt_bdcdata TYPE TABLE OF bdcdata.
FIELD-SYMBOLS: <ls_bdcdata> LIKE LINE OF lt_bdcdata.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-program = 'SAPMSSCF' ##NO_TEXT.
<ls_bdcdata>-dynpro = '1102' ##NO_TEXT.
<ls_bdcdata>-dynbegin = abap_true.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'BDC_OKCODE' ##NO_TEXT.
<ls_bdcdata>-fval = '=SHOW' ##NO_TEXT.
APPEND INITIAL LINE TO lt_bdcdata ASSIGNING <ls_bdcdata>.
<ls_bdcdata>-fnam = 'RSSCF-TDFORM' ##NO_TEXT.
<ls_bdcdata>-fval = ms_item-obj_name.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SE71'
mode_val = 'E'
TABLES
using_tab = lt_bdcdata
EXCEPTIONS
OTHERS = 1
##fm_subrc_ok. "#EC CI_SUBRC
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lt_form_data TYPE tyt_form_data.
DATA: ls_form_data TYPE tys_form_data.
DATA: lt_text_header TYPE tyt_text_header.
DATA: lt_lines TYPE tyt_lines.
DATA: lv_form_found TYPE flag.
FIELD-SYMBOLS: <ls_text_header> LIKE LINE OF lt_text_header.
lt_text_header = find_form( ms_item-obj_name ).
LOOP AT lt_text_header ASSIGNING <ls_text_header>.
CLEAR lt_lines.
CLEAR ls_form_data.
_read_form( EXPORTING is_text_header = <ls_text_header>
IMPORTING ev_form_found = lv_form_found
es_form_data = ls_form_data
et_lines = lt_lines ).
IF lv_form_found = abap_true.
_clear_changed_fields( CHANGING cs_form_data = ls_form_data ).
compress_lines( is_form_data = ls_form_data
it_lines = lt_lines ).
INSERT ls_form_data INTO TABLE lt_form_data.
ENDIF.
ENDLOOP.
IF lt_form_data IS NOT INITIAL.
io_xml->add( iv_name = c_objectname_form
ig_data = lt_form_data ).
ENDIF.
ENDMETHOD.
METHOD _clear_changed_fields.
CLEAR: cs_form_data-form_header-tdfuser,
cs_form_data-form_header-tdfdate,
cs_form_data-form_header-tdftime,
cs_form_data-form_header-tdfreles,
cs_form_data-form_header-tdluser,
cs_form_data-form_header-tdldate,
cs_form_data-form_header-tdltime,
cs_form_data-form_header-tdlreles.
CLEAR: cs_form_data-text_header-tdfuser,
cs_form_data-text_header-tdfdate,
cs_form_data-text_header-tdftime,
cs_form_data-text_header-tdfreles,
cs_form_data-text_header-tdluser,
cs_form_data-text_header-tdldate,
cs_form_data-text_header-tdltime,
cs_form_data-text_header-tdlreles.
ENDMETHOD.
METHOD _read_form.
CLEAR es_form_data.
CALL FUNCTION 'READ_FORM'
EXPORTING
form = is_text_header-tdform
language = is_text_header-tdspras
status = ' '
IMPORTING
form_header = es_form_data-form_header
found = ev_form_found
header = es_form_data-text_header
olanguage = es_form_data-orig_language
TABLES
form_lines = et_lines
pages = es_form_data-pages
page_windows = es_form_data-page_windows
paragraphs = es_form_data-paragraphs
strings = es_form_data-strings
tabs = es_form_data-tabs
windows = es_form_data-windows.
ENDMETHOD.
METHOD _save_form.
CALL FUNCTION 'SAVE_FORM'
EXPORTING
form_header = cs_form_data-form_header
TABLES
form_lines = it_lines
pages = cs_form_data-pages
page_windows = cs_form_data-page_windows
paragraphs = cs_form_data-paragraphs
strings = cs_form_data-strings
tabs = cs_form_data-tabs
windows = cs_form_data-windows.
CALL FUNCTION 'SAPSCRIPT_CHANGE_OLANGUAGE'
EXPORTING
forced = abap_true
name = cs_form_data-text_header-tdname
object = cs_form_data-text_header-tdobject
olanguage = cs_form_data-orig_language
EXCEPTIONS
OTHERS = 1
##fm_subrc_ok. "#EC CI_SUBRC
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ensc IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown. " todo
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_spot_name TYPE enhspotcompositename,
lv_message TYPE string,
lv_enh_shtext TYPE string,
lv_enh_spot TYPE enhspotname,
lt_enh_spots TYPE enhspotname_it,
lt_comp_spots TYPE enhspotname_it,
lx_root TYPE REF TO cx_root,
lv_package LIKE iv_package,
li_spot_ref TYPE REF TO if_enh_spot_composite,
lo_spot_ref TYPE REF TO cl_enh_spot_composite.
lv_spot_name = ms_item-obj_name.
io_xml->read( EXPORTING iv_name = 'SHORTTEXT'
CHANGING cg_data = lv_enh_shtext ).
io_xml->read( EXPORTING iv_name = 'ENH_SPOTS' "Enhancement spots
CHANGING cg_data = lt_enh_spots ).
io_xml->read( EXPORTING iv_name = 'COMP_ENH_SPOTS' "Composite enhancement spots
CHANGING cg_data = lt_comp_spots ).
IF zif_abapgit_object~exists( ) = abap_true.
zif_abapgit_object~delete( ).
ENDIF.
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement_spot_comp(
EXPORTING
name = lv_spot_name
run_dark = abap_true
IMPORTING
composite = li_spot_ref
CHANGING
devclass = lv_package ).
lo_spot_ref ?= li_spot_ref.
lo_spot_ref->if_enh_object_docu~set_shorttext( lv_enh_shtext ).
"Add subsequent enhancement spots
LOOP AT lt_enh_spots INTO lv_enh_spot.
lo_spot_ref->if_enh_spot_composite~add_enh_spot_child( lv_enh_spot ).
ENDLOOP.
"Add subsequent composite enhancement spots
LOOP AT lt_comp_spots INTO lv_enh_spot.
lo_spot_ref->if_enh_spot_composite~add_composite_child( lv_enh_spot ).
ENDLOOP.
lo_spot_ref->if_enh_object~save( ).
lo_spot_ref->if_enh_object~activate( ).
lo_spot_ref->if_enh_object~unlock( ).
CATCH cx_enh_root INTO lx_root.
lv_message = `Error occured while deserializing ENSC: `
&& lx_root->get_text( ) ##NO_TEXT.
zcx_abapgit_exception=>raise( lv_message ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_spot_name TYPE enhspotcompositename,
lv_message TYPE string,
lv_enh_shtext TYPE string,
lt_enh_spots TYPE enhspotname_it,
lt_comp_spots TYPE enhspotname_it,
lx_root TYPE REF TO cx_root,
li_spot_ref TYPE REF TO if_enh_spot_composite,
lo_spot_ref TYPE REF TO cl_enh_spot_composite.
lv_spot_name = ms_item-obj_name.
TRY.
li_spot_ref = cl_enh_factory=>get_enhancement_spot_comp(
lock = ''
name = lv_spot_name ).
lo_spot_ref ?= li_spot_ref.
lv_enh_shtext = li_spot_ref->if_enh_object_docu~get_shorttext( ).
"find parent = composite enhancement (ENSC)
"find subsequent enhancement spots
lt_enh_spots = lo_spot_ref->if_enh_spot_composite~get_enh_spot_childs( ).
"find subsequent composite enhancement spots
lt_comp_spots = lo_spot_ref->if_enh_spot_composite~get_composite_childs( ).
io_xml->add( ig_data = lv_enh_shtext
iv_name = 'SHORTTEXT' ).
io_xml->add( ig_data = lt_enh_spots
iv_name = 'ENH_SPOTS' ). "Enhancement spots
io_xml->add( ig_data = lt_comp_spots
iv_name = 'COMP_ENH_SPOTS' ). "Composite enhancement spots
CATCH cx_enh_root INTO lx_root.
lv_message = `Error occured while serializing ENSC: `
&& lx_root->get_text( ) ##NO_TEXT.
zcx_abapgit_exception=>raise( lv_message ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_spot_name TYPE enhspotcompositename,
li_spot_ref TYPE REF TO if_enh_spot_composite.
lv_spot_name = ms_item-obj_name.
TRY.
li_spot_ref = cl_enh_factory=>get_enhancement_spot_comp(
lock = ''
name = lv_spot_name ).
rv_bool = abap_true.
CATCH cx_enh_root.
rv_bool = abap_false.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_spot_name TYPE enhspotcompositename,
lv_message TYPE string,
lx_root TYPE REF TO cx_root,
li_spot_ref TYPE REF TO if_enh_spot_composite.
lv_spot_name = ms_item-obj_name.
TRY.
li_spot_ref = cl_enh_factory=>get_enhancement_spot_comp(
lock = 'X'
name = lv_spot_name ).
IF li_spot_ref IS BOUND.
li_spot_ref->if_enh_object~delete(
nevertheless_delete = 'X'
run_dark = 'X' ).
ENDIF.
li_spot_ref->if_enh_object~unlock( ).
CATCH cx_enh_root INTO lx_root.
lv_message = `Error occured while deleting ENSC: `
&& lx_root->get_text( ) ##NO_TEXT.
zcx_abapgit_exception=>raise( lv_message ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'ENSC'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_ENQU IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE as4user FROM dd25l
INTO rv_user
WHERE viewname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objname TYPE rsedd0-ddobjname.
lv_objname = ms_item-obj_name.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = abap_true
objname = lv_objname
objtype = 'L'
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, ENQU' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_name TYPE ddobjname,
ls_dd25v TYPE dd25v,
lt_dd26e TYPE TABLE OF dd26e,
lt_dd27p TYPE TABLE OF dd27p.
io_xml->read( EXPORTING iv_name = 'DD25V'
CHANGING cg_data = ls_dd25v ).
io_xml->read( EXPORTING iv_name = 'DD26E_TABLE'
CHANGING cg_data = lt_dd26e ).
io_xml->read( EXPORTING iv_name = 'DD27P_TABLE'
CHANGING cg_data = lt_dd27p ).
corr_insert( iv_package ).
lv_name = ms_item-obj_name.
CALL FUNCTION 'DDIF_ENQU_PUT'
EXPORTING
name = lv_name
dd25v_wa = ls_dd25v
TABLES
dd26e_tab = lt_dd26e
dd27p_tab = lt_dd27p
EXCEPTIONS
enqu_not_found = 1
name_inconsistent = 2
enqu_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_ENQU_PUT' ).
ENDIF.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_viewname TYPE dd25l-viewname.
SELECT SINGLE viewname FROM dd25l INTO lv_viewname
WHERE viewname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA: lv_date TYPE dats,
lv_time TYPE tims.
SELECT SINGLE as4date as4time FROM dd25l
INTO (lv_date, lv_time)
WHERE viewname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
jump_se11( iv_radio = 'RSRD1-ENQU'
iv_field = 'RSRD1-ENQU_VAL' ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_name TYPE ddobjname,
ls_dd25v TYPE dd25v,
lt_dd26e TYPE TABLE OF dd26e,
lt_dd27p TYPE TABLE OF dd27p.
lv_name = ms_item-obj_name.
CALL FUNCTION 'DDIF_ENQU_GET'
EXPORTING
name = lv_name
state = 'A'
langu = mv_language
IMPORTING
dd25v_wa = ls_dd25v
TABLES
dd26e_tab = lt_dd26e
dd27p_tab = lt_dd27p
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_ENQU_GET' ).
ENDIF.
IF ls_dd25v IS INITIAL.
RETURN. " does not exist in system
ENDIF.
CLEAR: ls_dd25v-as4user,
ls_dd25v-as4date,
ls_dd25v-as4time.
io_xml->add( iv_name = 'DD25V'
ig_data = ls_dd25v ).
io_xml->add( ig_data = lt_dd26e
iv_name = 'DD26E_TABLE' ).
io_xml->add( ig_data = lt_dd27p
iv_name = 'DD27P_TABLE' ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enhs_hook_d IMPLEMENTATION.
METHOD zif_abapgit_object_enhs~deserialize.
DATA: lv_enh_shorttext TYPE string,
ls_enh_hook_definition TYPE enh_hook_def,
ls_hook_definition TYPE ty_hook_defifnition,
li_enh_object TYPE REF TO if_enh_object,
li_enh_object_docu TYPE REF TO if_enh_object_docu,
lo_hookdef_tool TYPE REF TO cl_enh_tool_hook_def,
lx_error TYPE REF TO cx_enh_root,
lv_text TYPE string.
FIELD-SYMBOLS: <ls_hook_definition> TYPE enh_hook_def_ext.
io_xml->read( EXPORTING iv_name = 'SHORTTEXT'
CHANGING cg_data = lv_enh_shorttext ).
io_xml->read( EXPORTING iv_name = 'BADI_DATA'
CHANGING cg_data = ls_hook_definition ).
li_enh_object ?= ii_enh_spot_tool.
li_enh_object_docu ?= ii_enh_spot_tool.
TRY.
li_enh_object_docu->set_shorttext( lv_enh_shorttext ).
lo_hookdef_tool ?= ii_enh_spot_tool.
lo_hookdef_tool->set_original_object( pgmid = ls_hook_definition-pgmid
obj_name = ls_hook_definition-obj_name
obj_type = ls_hook_definition-obj_type
program = ls_hook_definition-program
main_type = ls_hook_definition-main_type
main_name = ls_hook_definition-main_name ).
LOOP AT ls_hook_definition-def_hooks ASSIGNING <ls_hook_definition>.
MOVE-CORRESPONDING <ls_hook_definition> TO ls_enh_hook_definition.
lo_hookdef_tool->add_hook_def( ls_enh_hook_definition ).
ENDLOOP.
li_enh_object->save( ).
li_enh_object->activate( ).
li_enh_object->unlock( ).
CATCH cx_enh_root INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object_enhs~serialize.
DATA: lo_hookdef_tool TYPE REF TO cl_enh_tool_hook_def,
lv_enh_shorttext TYPE string,
li_enh_object_docu TYPE REF TO if_enh_object_docu,
ls_hook_definition TYPE ty_hook_defifnition.
lo_hookdef_tool ?= ii_enh_spot_tool.
li_enh_object_docu ?= ii_enh_spot_tool.
lv_enh_shorttext = li_enh_object_docu->get_shorttext( ).
ls_hook_definition-def_hooks = lo_hookdef_tool->get_hook_defs( ).
lo_hookdef_tool->get_original_object(
IMPORTING
pgmid = ls_hook_definition-pgmid
obj_name = ls_hook_definition-obj_name
obj_type = ls_hook_definition-obj_type
main_type = ls_hook_definition-main_type
main_name = ls_hook_definition-main_name
program = ls_hook_definition-program ).
io_xml->add( ig_data = ii_enh_spot_tool->get_tool( )
iv_name = 'TOOL' ).
io_xml->add( ig_data = lv_enh_shorttext
iv_name = 'SHORTTEXT' ).
io_xml->add( ig_data = ls_hook_definition
iv_name = 'BADI_DATA' ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enhs_badi_d IMPLEMENTATION.
METHOD zif_abapgit_object_enhs~deserialize.
DATA: lv_parent TYPE enhspotcompositename,
lt_enh_badi TYPE enh_badi_data_it,
lo_badidef_tool TYPE REF TO cl_enh_tool_badi_def,
lv_enh_shorttext TYPE string,
li_enh_object TYPE REF TO if_enh_object,
li_enh_object_docu TYPE REF TO if_enh_object_docu,
lv_text TYPE string,
lx_error TYPE REF TO cx_enh_root.
FIELD-SYMBOLS: <ls_enh_badi> LIKE LINE OF lt_enh_badi.
io_xml->read( EXPORTING iv_name = 'PARENT_COMP'
CHANGING cg_data = lv_parent ).
io_xml->read( EXPORTING iv_name = 'BADI_DATA'
CHANGING cg_data = lt_enh_badi ).
io_xml->read( EXPORTING iv_name = 'SHORTTEXT'
CHANGING cg_data = lv_enh_shorttext ).
li_enh_object ?= ii_enh_spot_tool.
li_enh_object_docu ?= ii_enh_spot_tool.
TRY.
li_enh_object_docu->set_shorttext( lv_enh_shorttext ).
lo_badidef_tool ?= ii_enh_spot_tool.
LOOP AT lt_enh_badi ASSIGNING <ls_enh_badi>.
lo_badidef_tool->add_badi_def( <ls_enh_badi> ).
ENDLOOP.
li_enh_object->save( ).
li_enh_object->activate( ).
li_enh_object->unlock( ).
CATCH cx_enh_root INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object_enhs~serialize.
DATA: lv_spot_name TYPE enhspotname,
lv_parent TYPE enhspotcompositename,
lt_enh_badi TYPE enh_badi_data_it,
lo_badidef_tool TYPE REF TO cl_enh_tool_badi_def,
lv_enh_shorttext TYPE string,
li_enh_object_docu TYPE REF TO if_enh_object_docu.
lo_badidef_tool ?= ii_enh_spot_tool.
li_enh_object_docu ?= ii_enh_spot_tool.
lv_enh_shorttext = li_enh_object_docu->get_shorttext( ).
"get parent = composite enhs (ENHC)
lv_parent = cl_r3standard_persistence=>enh_find_parent_composite( lv_spot_name ).
"get subsequent BADI definitions
lt_enh_badi = lo_badidef_tool->get_badi_defs( ).
io_xml->add( ig_data = ii_enh_spot_tool->get_tool( )
iv_name = 'TOOL' ).
io_xml->add( ig_data = lv_enh_shorttext
iv_name = 'SHORTTEXT' ).
io_xml->add( ig_data = lv_parent
iv_name = 'PARENT_COMP' ).
io_xml->add( ig_data = lt_enh_badi
iv_name = 'BADI_DATA' ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enhs IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lv_spot_name TYPE enhspotname,
li_spot_ref TYPE REF TO if_enh_spot_tool.
lv_spot_name = ms_item-obj_name.
TRY.
li_spot_ref = cl_enh_factory=>get_enhancement_spot( lv_spot_name ).
li_spot_ref->get_attributes( IMPORTING changedby = rv_user ).
CATCH cx_enh_root.
rv_user = c_user_unknown.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_parent TYPE enhspotcompositename,
lv_spot_name TYPE enhspotname,
lv_tool TYPE enhspottooltype,
lv_package LIKE iv_package,
li_spot_ref TYPE REF TO if_enh_spot_tool,
li_enhs TYPE REF TO zif_abapgit_object_enhs,
lx_root TYPE REF TO cx_root.
IF zif_abapgit_object~exists( ) = abap_true.
zif_abapgit_object~delete( ).
ENDIF.
io_xml->read( EXPORTING iv_name = 'TOOL'
CHANGING cg_data = lv_tool ).
lv_spot_name = ms_item-obj_name.
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement_spot(
EXPORTING
spot_name = lv_spot_name
tooltype = lv_tool
dark = abap_false
compositename = lv_parent
IMPORTING
spot = li_spot_ref
CHANGING
devclass = lv_package ).
CATCH cx_enh_root INTO lx_root.
zcx_abapgit_exception=>raise( 'Error from CL_ENH_FACTORY' ).
ENDTRY.
li_enhs = factory( lv_tool ).
li_enhs->deserialize( io_xml = io_xml
iv_package = iv_package
ii_enh_spot_tool = li_spot_ref ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_spot_name TYPE enhspotname,
li_spot_ref TYPE REF TO if_enh_spot_tool,
li_enhs TYPE REF TO zif_abapgit_object_enhs,
lx_root TYPE REF TO cx_root.
lv_spot_name = ms_item-obj_name.
TRY.
li_spot_ref = cl_enh_factory=>get_enhancement_spot( lv_spot_name ).
CATCH cx_enh_root INTO lx_root.
zcx_abapgit_exception=>raise( 'Error from CL_ENH_FACTORY' ).
ENDTRY.
li_enhs = factory( li_spot_ref->get_tool( ) ).
li_enhs->serialize( io_xml = io_xml
ii_enh_spot_tool = li_spot_ref ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_spot_name TYPE enhspotname,
li_spot_ref TYPE REF TO if_enh_spot_tool.
lv_spot_name = ms_item-obj_name.
TRY.
li_spot_ref = cl_enh_factory=>get_enhancement_spot( lv_spot_name ).
rv_bool = abap_true.
CATCH cx_enh_root.
rv_bool = abap_false.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_spot_name TYPE enhspotname,
li_enh_object TYPE REF TO if_enh_object,
lx_root TYPE REF TO cx_root.
lv_spot_name = ms_item-obj_name.
TRY.
li_enh_object ?= cl_enh_factory=>get_enhancement_spot( spot_name = lv_spot_name
lock = abap_true ).
li_enh_object->delete( nevertheless_delete = abap_true
run_dark = abap_true ).
li_enh_object->unlock( ).
CATCH cx_enh_root INTO lx_root.
zcx_abapgit_exception=>raise( 'Error from CL_ENH_FACTORY' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'ENHS'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD factory.
CASE iv_tool.
WHEN cl_enh_tool_badi_def=>tooltype.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enhs_badi_d.
WHEN cl_enh_tool_hook_def=>tool_type.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enhs_hook_d.
WHEN OTHERS.
zcx_abapgit_exception=>raise( |ENHS: Unsupported tool { iv_tool }| ).
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_ENHO_WDYN IMPLEMENTATION.
METHOD constructor.
ms_item = is_item.
ENDMETHOD.
METHOD zif_abapgit_object_enho~deserialize.
DATA: ls_enh_data TYPE enhwdyn,
li_tool TYPE REF TO if_enh_tool,
lo_wdyn TYPE REF TO cl_enh_tool_wdy,
lv_tool_type TYPE enhtooltype,
lv_package TYPE devclass.
FIELD-SYMBOLS: <ls_controller_data> TYPE enhwdyc,
<ls_view_data> TYPE enhwdyv.
io_xml->read(
EXPORTING
iv_name = 'TOOL'
CHANGING
cg_data = lv_tool_type ).
io_xml->read(
EXPORTING
iv_name = 'COMPONENT_DATA'
CHANGING
cg_data = ls_enh_data ).
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement(
EXPORTING
enhname = |{ ms_item-obj_name }|
enhtype = ''
enhtooltype = lv_tool_type
IMPORTING
enhancement = li_tool
CHANGING
devclass = lv_package ).
lo_wdyn ?= li_tool.
lo_wdyn->initialize( ls_enh_data-component_name ).
lo_wdyn->set_component_data( ls_enh_data-component_data ).
LOOP AT ls_enh_data-controller_data ASSIGNING <ls_controller_data>.
lo_wdyn->set_controller_data( p_controller_name = <ls_controller_data>-controller_name
p_enh_data = <ls_controller_data> ).
ENDLOOP.
LOOP AT ls_enh_data-view_data ASSIGNING <ls_view_data>.
lo_wdyn->set_view_data( p_view_name = <ls_view_data>-view_name
p_enh_data = <ls_view_data> ).
ENDLOOP.
lo_wdyn->if_enh_object~save( ).
lo_wdyn->if_enh_object~unlock( ).
CATCH cx_root.
zcx_abapgit_exception=>raise( |error deserializing ENHO wdyn { ms_item-obj_name }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object_enho~serialize.
DATA: lo_wdyn TYPE REF TO cl_enh_tool_wdy,
lv_component_name TYPE wdy_component_name,
ls_enh_data TYPE enhwdyn.
lo_wdyn ?= ii_enh_tool.
lv_component_name = lo_wdyn->get_component_name( ).
TRY.
lo_wdyn->get_all_data_for_comp(
EXPORTING
p_component_name = lv_component_name
IMPORTING
p_enh_data = ls_enh_data ).
io_xml->add( iv_name = 'TOOL'
ig_data = ii_enh_tool->get_tool( ) ).
io_xml->add( iv_name = 'COMPONENT_DATA'
ig_data = ls_enh_data ).
CATCH cx_enh_not_found.
zcx_abapgit_exception=>raise( |error serializing ENHO wdyn { ms_item-obj_name }| ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enho_wdyc IMPLEMENTATION.
METHOD constructor.
ms_item = is_item.
ENDMETHOD.
METHOD zif_abapgit_object_enho~deserialize.
DATA: lv_enhname TYPE enhname,
lo_wdyconf TYPE REF TO cl_wdr_cfg_enhancement,
li_tool TYPE REF TO if_enh_tool,
ls_obj TYPE wdy_config_key,
lv_package TYPE devclass.
io_xml->read( EXPORTING iv_name = 'ORIGINAL_OBJECT'
CHANGING cg_data = ls_obj ).
lv_enhname = ms_item-obj_name.
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement(
EXPORTING
enhname = lv_enhname
enhtype = ''
enhtooltype = cl_wdr_cfg_enhancement=>tooltype
IMPORTING
enhancement = li_tool
CHANGING
devclass = lv_package ).
lo_wdyconf ?= li_tool.
ASSERT 0 = 1.
lo_wdyconf->if_enh_object~save( ).
lo_wdyconf->if_enh_object~unlock( ).
CATCH cx_enh_root.
zcx_abapgit_exception=>raise( 'error deserializing ENHO wdyconf' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object_enho~serialize.
DATA: lo_wdyconf TYPE REF TO cl_wdr_cfg_enhancement,
lt_data TYPE wdy_cfg_expl_data_tab,
ls_outline TYPE wdy_cfg_outline_data,
ls_obj TYPE wdy_config_key,
li_document TYPE REF TO if_ixml_document,
li_element TYPE REF TO if_ixml_element.
lo_wdyconf ?= ii_enh_tool.
ls_obj = lo_wdyconf->get_original_object( ).
io_xml->add( iv_name = 'TOOL'
ig_data = ii_enh_tool->get_tool( ) ).
io_xml->add( iv_name = 'ORIGINAL_OBJECT'
ig_data = ls_obj ).
CALL METHOD lo_wdyconf->('GET_ENHANCEMENT_DATA')
EXPORTING
p_scope = 1
IMPORTING
p_enh_data = lt_data.
CALL METHOD cl_wdr_cfg_persistence_utils=>('COMP_TABLES_TO_XML')
EXPORTING
outline_data = ls_outline
expl_data_tab = lt_data
IMPORTING
element = li_element
CHANGING
document = li_document.
io_xml->add_xml( iv_name = 'ENHANCEMENT_DATA'
ii_xml = li_element ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enho_intf IMPLEMENTATION.
METHOD constructor.
ms_item = is_item.
mo_files = io_files.
ENDMETHOD.
METHOD zif_abapgit_object_enho~serialize.
DATA: lo_enh_intf TYPE REF TO cl_enh_tool_intf,
lv_class TYPE seoclsname,
lv_shorttext TYPE string.
lo_enh_intf ?= ii_enh_tool.
lv_shorttext = lo_enh_intf->if_enh_object_docu~get_shorttext( ).
lo_enh_intf->get_class( IMPORTING class_name = lv_class ).
io_xml->add( iv_name = 'TOOL'
ig_data = ii_enh_tool->get_tool( ) ).
io_xml->add( ig_data = lv_shorttext
iv_name = 'SHORTTEXT' ).
io_xml->add( iv_name = 'CLASS'
ig_data = lv_class ).
zcl_abapgit_object_enho_clif=>serialize(
io_xml = io_xml
io_files = mo_files
io_clif = lo_enh_intf ).
ENDMETHOD.
METHOD zif_abapgit_object_enho~deserialize.
DATA: lo_enh_intf TYPE REF TO cl_enh_tool_intf,
li_tool TYPE REF TO if_enh_tool,
lv_shorttext TYPE string,
lv_class TYPE seoclsname,
lv_enhname TYPE enhname,
lv_package TYPE devclass.
io_xml->read( EXPORTING iv_name = 'SHORTTEXT'
CHANGING cg_data = lv_shorttext ).
io_xml->read( EXPORTING iv_name = 'CLASS'
CHANGING cg_data = lv_class ).
lv_enhname = ms_item-obj_name.
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement(
EXPORTING
enhname = lv_enhname
enhtype = ''
enhtooltype = cl_enh_tool_intf=>tooltype
IMPORTING
enhancement = li_tool
CHANGING
devclass = lv_package ).
lo_enh_intf ?= li_tool.
lo_enh_intf->if_enh_object_docu~set_shorttext( lv_shorttext ).
lo_enh_intf->set_class( lv_class ).
zcl_abapgit_object_enho_clif=>deserialize(
io_xml = io_xml
io_clif = lo_enh_intf ).
lo_enh_intf->if_enh_object~save( ).
lo_enh_intf->if_enh_object~unlock( ).
CATCH cx_enh_root.
zcx_abapgit_exception=>raise( 'error deserializing ENHO interface' ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enho_hook IMPLEMENTATION.
METHOD constructor.
ms_item = is_item.
mo_files = io_files.
ENDMETHOD.
METHOD zif_abapgit_object_enho~serialize.
DATA: lv_shorttext TYPE string,
lo_hook_impl TYPE REF TO cl_enh_tool_hook_impl,
ls_original_object TYPE enh_hook_admin,
lt_spaces TYPE ty_spaces_tt,
lt_enhancements TYPE enh_hook_impl_it.
lo_hook_impl ?= ii_enh_tool.
lv_shorttext = lo_hook_impl->if_enh_object_docu~get_shorttext( ).
lo_hook_impl->get_original_object(
IMPORTING
pgmid = ls_original_object-pgmid
obj_name = ls_original_object-org_obj_name
obj_type = ls_original_object-org_obj_type
main_type = ls_original_object-org_main_type
main_name = ls_original_object-org_main_name
program = ls_original_object-programname ).
ls_original_object-include_bound = lo_hook_impl->get_include_bound( ).
lt_enhancements = lo_hook_impl->get_hook_impls( ).
hook_impl_serialize(
IMPORTING et_spaces = lt_spaces
CHANGING ct_impl = lt_enhancements ).
io_xml->add( iv_name = 'TOOL'
ig_data = ii_enh_tool->get_tool( ) ).
io_xml->add( ig_data = lv_shorttext
iv_name = 'SHORTTEXT' ).
io_xml->add( ig_data = ls_original_object
iv_name = 'ORIGINAL_OBJECT' ).
io_xml->add( iv_name = 'ENHANCEMENTS'
ig_data = lt_enhancements ).
io_xml->add( iv_name = 'SPACES'
ig_data = lt_spaces ).
ENDMETHOD.
METHOD hook_impl_serialize.
FIELD-SYMBOLS: <ls_impl> LIKE LINE OF ct_impl,
<ls_space> LIKE LINE OF et_spaces,
<lv_space> TYPE i,
<lv_line> TYPE string.
LOOP AT ct_impl ASSIGNING <ls_impl>.
APPEND INITIAL LINE TO et_spaces ASSIGNING <ls_space>.
<ls_space>-full_name = <ls_impl>-full_name.
LOOP AT <ls_impl>-source ASSIGNING <lv_line>.
APPEND INITIAL LINE TO <ls_space>-spaces ASSIGNING <lv_space>.
WHILE strlen( <lv_line> ) >= 1 AND <lv_line>(1) = ` `.
<lv_line> = <lv_line>+1.
<lv_space> = <lv_space> + 1.
ENDWHILE.
ENDLOOP.
ENDLOOP.
ENDMETHOD.
METHOD hook_impl_deserialize.
FIELD-SYMBOLS: <ls_impl> LIKE LINE OF ct_impl,
<lv_line> TYPE string,
<lv_space> TYPE i,
<ls_spaces> LIKE LINE OF it_spaces.
LOOP AT ct_impl ASSIGNING <ls_impl>.
READ TABLE it_spaces ASSIGNING <ls_spaces> WITH KEY full_name = <ls_impl>-full_name.
IF sy-subrc = 0.
LOOP AT <ls_impl>-source ASSIGNING <lv_line>.
READ TABLE <ls_spaces>-spaces ASSIGNING <lv_space> INDEX sy-tabix.
IF sy-subrc = 0 AND <lv_space> > 0.
DO <lv_space> TIMES.
CONCATENATE space <lv_line> INTO <lv_line> RESPECTING BLANKS.
ENDDO.
ENDIF.
ENDLOOP.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object_enho~deserialize.
DATA: lv_shorttext TYPE string,
lo_hook_impl TYPE REF TO cl_enh_tool_hook_impl,
li_tool TYPE REF TO if_enh_tool,
lv_enhname TYPE enhname,
lv_package TYPE devclass,
ls_original_object TYPE enh_hook_admin,
lt_spaces TYPE ty_spaces_tt,
lt_enhancements TYPE enh_hook_impl_it,
lx_enh_root TYPE REF TO cx_enh_root.
FIELD-SYMBOLS: <ls_enhancement> LIKE LINE OF lt_enhancements.
io_xml->read( EXPORTING iv_name = 'SHORTTEXT'
CHANGING cg_data = lv_shorttext ).
io_xml->read( EXPORTING iv_name = 'ORIGINAL_OBJECT'
CHANGING cg_data = ls_original_object ).
io_xml->read( EXPORTING iv_name = 'ENHANCEMENTS'
CHANGING cg_data = lt_enhancements ).
io_xml->read( EXPORTING iv_name = 'SPACES'
CHANGING cg_data = lt_spaces ).
hook_impl_deserialize( EXPORTING it_spaces = lt_spaces
CHANGING ct_impl = lt_enhancements ).
lv_enhname = ms_item-obj_name.
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement(
EXPORTING
enhname = lv_enhname
enhtype = cl_abstract_enh_tool_redef=>credefinition
enhtooltype = cl_enh_tool_hook_impl=>tooltype
IMPORTING
enhancement = li_tool
CHANGING
devclass = lv_package ).
lo_hook_impl ?= li_tool.
lo_hook_impl->if_enh_object_docu~set_shorttext( lv_shorttext ).
lo_hook_impl->set_original_object(
pgmid = ls_original_object-pgmid
obj_name = ls_original_object-org_obj_name
obj_type = ls_original_object-org_obj_type
program = ls_original_object-programname
main_type = ls_original_object-org_main_type
main_name = ls_original_object-org_main_name ).
lo_hook_impl->set_include_bound( ls_original_object-include_bound ).
LOOP AT lt_enhancements ASSIGNING <ls_enhancement>.
lo_hook_impl->add_hook_impl(
overwrite = <ls_enhancement>-overwrite
method = <ls_enhancement>-method
enhmode = <ls_enhancement>-enhmode
full_name = <ls_enhancement>-full_name
source = <ls_enhancement>-source
spot = <ls_enhancement>-spotname
parent_full_name = <ls_enhancement>-parent_full_name ).
ENDLOOP.
lo_hook_impl->if_enh_object~save( run_dark = abap_true ).
lo_hook_impl->if_enh_object~unlock( ).
CATCH cx_enh_root INTO lx_enh_root.
zcx_abapgit_exception=>raise( lx_enh_root->get_text( ) ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_ENHO_FUGR IMPLEMENTATION.
METHOD constructor.
ms_item = is_item.
mo_files = io_files.
ENDMETHOD.
METHOD zif_abapgit_object_enho~deserialize.
DATA: lo_fugrdata TYPE REF TO cl_enh_tool_fugr,
ls_enha_data TYPE enhfugrdata,
li_tool TYPE REF TO if_enh_tool,
lv_tool TYPE enhtooltype,
lv_package TYPE devclass.
FIELD-SYMBOLS: <ls_fuba> TYPE enhfugrfuncdata.
io_xml->read(
EXPORTING
iv_name = 'TOOL'
CHANGING
cg_data = lv_tool ).
io_xml->read(
EXPORTING
iv_name = 'FUGRDATA'
CHANGING
cg_data = ls_enha_data ).
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement(
EXPORTING
enhname = |{ ms_item-obj_name }|
enhtype = ''
enhtooltype = lv_tool
IMPORTING
enhancement = li_tool
CHANGING
devclass = lv_package ).
lo_fugrdata ?= li_tool.
lo_fugrdata->set_fugr( ls_enha_data-fugr ).
LOOP AT ls_enha_data-enh_fubas ASSIGNING <ls_fuba>.
lo_fugrdata->set_func_data( func_name = <ls_fuba>-fuba
func_enhadata = <ls_fuba> ).
ENDLOOP.
lo_fugrdata->if_enh_object~save( ).
lo_fugrdata->if_enh_object~unlock( ).
CATCH cx_enh_root.
zcx_abapgit_exception=>raise( |error deserializing ENHO fugrdata { ms_item-obj_name }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object_enho~serialize.
DATA: lo_fugrdata TYPE REF TO cl_enh_tool_fugr,
lv_fugr_name TYPE rs38l-area,
ls_enha_data TYPE enhfugrdata.
FIELD-SYMBOLS: <ls_docuobj> TYPE enhfugrparamdocu.
lo_fugrdata ?= ii_enh_tool.
lo_fugrdata->get_fugr(
IMPORTING
fugr_name = lv_fugr_name ).
TRY.
lo_fugrdata->get_all_data_for_fugr(
EXPORTING
fugr_name = lv_fugr_name
IMPORTING
enha_data = ls_enha_data ).
LOOP AT ls_enha_data-docuobjs ASSIGNING <ls_docuobj>.
CLEAR: <ls_docuobj>-shorttext,
<ls_docuobj>-longtext.
ENDLOOP.
CATCH cx_enh_not_found.
zcx_abapgit_exception=>raise( |error deserializing ENHO fugrdata { ms_item-obj_name }| ).
ENDTRY.
io_xml->add( iv_name = 'TOOL'
ig_data = lo_fugrdata->if_enh_tool~get_tool( ) ).
io_xml->add( iv_name = 'FUGRDATA'
ig_data = ls_enha_data ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enho_clif IMPLEMENTATION.
METHOD serialize_includes.
DATA: lt_includes TYPE enhnewmeth_tabincl_plus_enha,
lt_source TYPE TABLE OF abaptxt255,
lv_include TYPE programm.
FIELD-SYMBOLS: <ls_include> LIKE LINE OF lt_includes.
lt_includes = io_clif->get_enh_method_includes( ).
LOOP AT lt_includes ASSIGNING <ls_include>.
lv_include = io_clif->if_enh_tool~get_name( ).
TRANSLATE lv_include USING ' ='.
lv_include+30 = 'EM'.
lv_include+32(8) = <ls_include>-includenr.
CALL FUNCTION 'RPY_PROGRAM_READ'
EXPORTING
program_name = lv_include
with_lowercase = abap_true
TABLES
source_extended = lt_source
EXCEPTIONS
cancelled = 1
not_found = 2
permission_error = 3
OTHERS = 4.
IF sy-subrc = 0.
io_files->add_abap( iv_extra = |EM{ <ls_include>-includenr }|
it_abap = lt_source ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD serialize.
DATA: lt_tab_attributes TYPE enhclasstabattrib,
lt_tab_methods TYPE enhnewmeth_tab.
FIELD-SYMBOLS: <ls_attr> LIKE LINE OF lt_tab_attributes,
<ls_meth> LIKE LINE OF lt_tab_methods.
io_clif->get_enhattributes(
IMPORTING
tab_attributes = lt_tab_attributes ).
io_clif->get_enh_new_methodes(
IMPORTING
tab_methodes = lt_tab_methods ).
serialize_includes( io_clif = io_clif
io_files = io_files ).
LOOP AT lt_tab_attributes ASSIGNING <ls_attr>.
CLEAR: <ls_attr>-author,
<ls_attr>-createdon,
<ls_attr>-changedby,
<ls_attr>-changedon.
ENDLOOP.
LOOP AT lt_tab_methods ASSIGNING <ls_meth>.
CLEAR: <ls_meth>-meth_header-author,
<ls_meth>-meth_header-createdon,
<ls_meth>-meth_header-changedby,
<ls_meth>-meth_header-changedon,
<ls_meth>-meth_header-descript_id.
ENDLOOP.
io_xml->add( iv_name = 'TAB_ATTRIBUTES'
ig_data = lt_tab_attributes ).
io_xml->add( iv_name = 'TAB_METHODS'
ig_data = lt_tab_methods ).
ENDMETHOD.
METHOD deserialize.
DATA: lt_tab_attributes TYPE enhclasstabattrib,
lt_tab_methods TYPE enhnewmeth_tab,
ls_header TYPE vseomethod,
ls_param TYPE vseomepara,
ls_exc TYPE vseoexcep.
FIELD-SYMBOLS: <ls_method> LIKE LINE OF lt_tab_methods,
<ls_param> LIKE LINE OF <ls_method>-meth_param,
<ls_exc> LIKE LINE OF <ls_method>-meth_exc.
io_xml->read( EXPORTING iv_name = 'TAB_ATTRIBUTES'
CHANGING cg_data = lt_tab_attributes ).
io_xml->read( EXPORTING iv_name = 'TAB_METHODS'
CHANGING cg_data = lt_tab_methods ).
io_clif->set_enhattributes( lt_tab_attributes ).
LOOP AT lt_tab_methods ASSIGNING <ls_method>.
MOVE-CORRESPONDING <ls_method>-meth_header TO ls_header.
io_clif->add_change_new_enh_method(
methkey = <ls_method>-methkey
method_header = ls_header ).
LOOP AT <ls_method>-meth_param ASSIGNING <ls_param>.
MOVE-CORRESPONDING <ls_param> TO ls_param.
io_clif->add_change_enh_methparam(
methname = <ls_method>-methkey-cmpname
param_line = ls_param ).
ENDLOOP.
LOOP AT <ls_method>-meth_exc ASSIGNING <ls_exc>.
MOVE-CORRESPONDING <ls_exc> TO ls_exc.
io_clif->add_change_enh_methexc(
methname = <ls_method>-methkey-cmpname
except_line = ls_exc ).
ENDLOOP.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enho_class IMPLEMENTATION.
METHOD constructor.
ms_item = is_item.
mo_files = io_files.
ENDMETHOD.
METHOD zif_abapgit_object_enho~serialize.
DATA: lo_enh_class TYPE REF TO cl_enh_tool_class,
lt_owr TYPE enhmeth_tabkeys,
lt_pre TYPE enhmeth_tabkeys,
lt_post TYPE enhmeth_tabkeys,
lt_source TYPE rswsourcet,
lv_class TYPE seoclsname,
lv_shorttext TYPE string.
lo_enh_class ?= ii_enh_tool.
lv_shorttext = lo_enh_class->if_enh_object_docu~get_shorttext( ).
lt_owr = lo_enh_class->get_owr_methods( ).
lt_pre = lo_enh_class->get_pre_methods( ).
lt_post = lo_enh_class->get_post_methods( ).
lt_source = lo_enh_class->get_eimp_include( ).
lo_enh_class->get_class( IMPORTING class_name = lv_class ).
io_xml->add( iv_name = 'TOOL'
ig_data = ii_enh_tool->get_tool( ) ).
io_xml->add( ig_data = lv_shorttext
iv_name = 'SHORTTEXT' ).
io_xml->add( iv_name = 'CLASS'
ig_data = lv_class ).
io_xml->add( iv_name = 'OWR_METHODS'
ig_data = lt_owr ).
io_xml->add( iv_name = 'PRE_METHODS'
ig_data = lt_pre ).
io_xml->add( iv_name = 'POST_METHODS'
ig_data = lt_post ).
mo_files->add_abap( lt_source ).
zcl_abapgit_object_enho_clif=>serialize(
io_xml = io_xml
io_files = mo_files
io_clif = lo_enh_class ).
ENDMETHOD.
METHOD zif_abapgit_object_enho~deserialize.
DATA: lo_enh_class TYPE REF TO cl_enh_tool_class,
lt_owr TYPE enhmeth_tabkeys,
lt_pre TYPE enhmeth_tabkeys,
lt_post TYPE enhmeth_tabkeys,
lt_source TYPE rswsourcet,
li_tool TYPE REF TO if_enh_tool,
lv_shorttext TYPE string,
lv_class TYPE seoclsname,
lv_enhname TYPE enhname,
lv_package TYPE devclass.
io_xml->read( EXPORTING iv_name = 'SHORTTEXT'
CHANGING cg_data = lv_shorttext ).
io_xml->read( EXPORTING iv_name = 'OWR_METHODS'
CHANGING cg_data = lt_owr ).
io_xml->read( EXPORTING iv_name = 'PRE_METHODS'
CHANGING cg_data = lt_pre ).
io_xml->read( EXPORTING iv_name = 'POST_METHODS'
CHANGING cg_data = lt_post ).
io_xml->read( EXPORTING iv_name = 'CLASS'
CHANGING cg_data = lv_class ).
lt_source = mo_files->read_abap( ).
lv_enhname = ms_item-obj_name.
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement(
EXPORTING
enhname = lv_enhname
enhtype = ''
enhtooltype = cl_enh_tool_class=>tooltype
IMPORTING
enhancement = li_tool
CHANGING
devclass = lv_package ).
lo_enh_class ?= li_tool.
lo_enh_class->if_enh_object_docu~set_shorttext( lv_shorttext ).
lo_enh_class->set_class( lv_class ).
lo_enh_class->set_owr_methods( version = 'I'
owr_methods = lt_owr ).
lo_enh_class->set_pre_methods( version = 'I'
pre_methods = lt_pre ).
lo_enh_class->set_post_methods( version = 'I'
post_methods = lt_post ).
lo_enh_class->set_eimp_include( version = 'I'
eimp_source = lt_source ).
zcl_abapgit_object_enho_clif=>deserialize(
io_xml = io_xml
io_clif = lo_enh_class ).
lo_enh_class->if_enh_object~save( ).
lo_enh_class->if_enh_object~unlock( ).
CATCH cx_enh_root.
zcx_abapgit_exception=>raise( 'error deserializing ENHO class' ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enho_badi IMPLEMENTATION.
METHOD constructor.
ms_item = is_item.
ENDMETHOD.
METHOD zif_abapgit_object_enho~serialize.
DATA: lo_badi_impl TYPE REF TO cl_enh_tool_badi_impl,
lv_spot_name TYPE enhspotname,
lv_shorttext TYPE string,
lt_impl TYPE enh_badi_impl_data_it.
FIELD-SYMBOLS: <ls_impl> LIKE LINE OF lt_impl,
<ls_values> LIKE LINE OF <ls_impl>-filter_values,
<ls_filter> LIKE LINE OF <ls_impl>-filters.
lo_badi_impl ?= ii_enh_tool.
lv_shorttext = lo_badi_impl->if_enh_object_docu~get_shorttext( ).
lv_spot_name = lo_badi_impl->get_spot_name( ).
lt_impl = lo_badi_impl->get_implementations( ).
LOOP AT lt_impl ASSIGNING <ls_impl>.
LOOP AT <ls_impl>-filter_values ASSIGNING <ls_values>.
IF <ls_values>-filter_numeric_value1 CA space.
CLEAR <ls_values>-filter_numeric_value1.
ENDIF.
ENDLOOP.
LOOP AT <ls_impl>-filters ASSIGNING <ls_filter>.
IF <ls_filter>-filter_numeric_value1 CA space.
CLEAR <ls_filter>-filter_numeric_value1.
ENDIF.
ENDLOOP.
ENDLOOP.
io_xml->add( iv_name = 'TOOL'
ig_data = ii_enh_tool->get_tool( ) ).
io_xml->add( ig_data = lv_shorttext
iv_name = 'SHORTTEXT' ).
io_xml->add( iv_name = 'SPOT_NAME'
ig_data = lv_spot_name ).
io_xml->add( iv_name = 'IMPL'
ig_data = lt_impl ).
ENDMETHOD.
METHOD zif_abapgit_object_enho~deserialize.
DATA: lv_spot_name TYPE enhspotname,
lv_shorttext TYPE string,
lv_enhname TYPE enhname,
lo_badi TYPE REF TO cl_enh_tool_badi_impl,
li_tool TYPE REF TO if_enh_tool,
lv_package TYPE devclass,
lt_impl TYPE enh_badi_impl_data_it.
FIELD-SYMBOLS: <ls_impl> LIKE LINE OF lt_impl.
io_xml->read( EXPORTING iv_name = 'SHORTTEXT'
CHANGING cg_data = lv_shorttext ).
io_xml->read( EXPORTING iv_name = 'SPOT_NAME'
CHANGING cg_data = lv_spot_name ).
io_xml->read( EXPORTING iv_name = 'IMPL'
CHANGING cg_data = lt_impl ).
lv_enhname = ms_item-obj_name.
lv_package = iv_package.
TRY.
cl_enh_factory=>create_enhancement(
EXPORTING
enhname = lv_enhname
enhtype = cl_abstract_enh_tool_redef=>credefinition
enhtooltype = cl_enh_tool_badi_impl=>tooltype
IMPORTING
enhancement = li_tool
CHANGING
devclass = lv_package ).
lo_badi ?= li_tool.
lo_badi->set_spot_name( lv_spot_name ).
lo_badi->if_enh_object_docu~set_shorttext( lv_shorttext ).
LOOP AT lt_impl ASSIGNING <ls_impl>.
lo_badi->add_implementation( <ls_impl> ).
ENDLOOP.
lo_badi->if_enh_object~save( ).
lo_badi->if_enh_object~unlock( ).
CATCH cx_enh_root.
zcx_abapgit_exception=>raise( 'error deserializing ENHO badi' ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_enho IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lv_enh_id TYPE enhname,
li_enho TYPE REF TO zif_abapgit_object_enho,
lt_log TYPE enh_log_it,
li_log_obj TYPE REF TO if_enh_log,
ls_enhlog TYPE enhlog,
lv_lines TYPE i,
lt_enhlog TYPE STANDARD TABLE OF enhlog WITH DEFAULT KEY,
li_enh_tool TYPE REF TO if_enh_tool.
lv_enh_id = ms_item-obj_name.
TRY.
li_enh_tool = cl_enh_factory=>get_enhancement(
enhancement_id = lv_enh_id
bypassing_buffer = abap_true ).
CATCH cx_enh_root.
rv_user = c_user_unknown.
RETURN.
ENDTRY.
lt_log = li_enh_tool->get_log( ).
LOOP AT lt_log INTO li_log_obj.
ls_enhlog = li_log_obj->get_enhlog( ).
APPEND ls_enhlog TO lt_enhlog.
ENDLOOP.
lv_lines = lines( lt_enhlog ).
READ TABLE lt_enhlog INTO ls_enhlog INDEX lv_lines.
IF sy-subrc = 0.
rv_user = ls_enhlog-loguser.
ELSE.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_enh_id TYPE enhname.
lv_enh_id = ms_item-obj_name.
TRY.
cl_enh_factory=>get_enhancement(
enhancement_id = lv_enh_id
bypassing_buffer = abap_true ).
rv_bool = abap_true.
CATCH cx_enh_root.
rv_bool = abap_false.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_enh_id TYPE enhname,
li_enho TYPE REF TO zif_abapgit_object_enho,
li_enh_tool TYPE REF TO if_enh_tool.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
lv_enh_id = ms_item-obj_name.
TRY.
li_enh_tool = cl_enh_factory=>get_enhancement(
enhancement_id = lv_enh_id
bypassing_buffer = abap_true ).
CATCH cx_enh_root.
zcx_abapgit_exception=>raise( 'Error from CL_ENH_FACTORY' ).
ENDTRY.
li_enho = factory( li_enh_tool->get_tool( ) ).
li_enho->serialize( io_xml = io_xml
ii_enh_tool = li_enh_tool ).
ENDMETHOD.
METHOD factory.
CASE iv_tool.
WHEN cl_enh_tool_badi_impl=>tooltype.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enho_badi
EXPORTING
is_item = ms_item
io_files = mo_files.
WHEN cl_enh_tool_hook_impl=>tooltype.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enho_hook
EXPORTING
is_item = ms_item
io_files = mo_files.
WHEN cl_enh_tool_class=>tooltype.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enho_class
EXPORTING
is_item = ms_item
io_files = mo_files.
WHEN cl_enh_tool_intf=>tooltype.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enho_intf
EXPORTING
is_item = ms_item
io_files = mo_files.
WHEN cl_wdr_cfg_enhancement=>tooltype.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enho_wdyc
EXPORTING
is_item = ms_item
io_files = mo_files.
WHEN 'FUGRENH'.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enho_fugr
EXPORTING
is_item = ms_item
io_files = mo_files.
WHEN 'WDYENH'.
CREATE OBJECT ri_enho TYPE zcl_abapgit_object_enho_wdyn
EXPORTING
is_item = ms_item
io_files = mo_files.
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Unsupported ENHO type { iv_tool }| ).
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_tool TYPE enhtooltype,
li_enho TYPE REF TO zif_abapgit_object_enho.
IF zif_abapgit_object~exists( ) = abap_true.
zif_abapgit_object~delete( ).
ENDIF.
io_xml->read( EXPORTING iv_name = 'TOOL'
CHANGING cg_data = lv_tool ).
li_enho = factory( lv_tool ).
li_enho->deserialize( io_xml = io_xml
iv_package = iv_package ).
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_enh_id TYPE enhname,
li_enh_object TYPE REF TO if_enh_object.
lv_enh_id = ms_item-obj_name.
TRY.
li_enh_object = cl_enh_factory=>get_enhancement(
enhancement_id = lv_enh_id
lock = abap_true ).
li_enh_object->delete( ).
li_enh_object->save( ).
li_enh_object->unlock( ).
CATCH cx_enh_root.
zcx_abapgit_exception=>raise( 'Error deleting ENHO' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'ENHO'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE seqg3-garg.
lv_object = |{ ms_item-obj_type }{ ms_item-obj_name }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'E_ENHANCE'
iv_argument = lv_object ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ecvo IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
ENDMETHOD.
METHOD get_object_type.
rv_object_type = 'ECVO'.
ENDMETHOD.
METHOD get_upload.
CREATE OBJECT ro_upload TYPE zcl_abapgit_ecatt_val_obj_upl.
ENDMETHOD.
METHOD get_download.
CREATE OBJECT ro_download TYPE zcl_abapgit_ecatt_val_obj_down.
ENDMETHOD.
METHOD get_lock_object.
rv_lock_object = 'E_ECATT_TD'.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ectd IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
ENDMETHOD.
METHOD get_object_type.
rv_object_type = cl_apl_ecatt_const=>obj_type_test_data.
ENDMETHOD.
METHOD get_upload.
CREATE OBJECT ro_upload TYPE zcl_abapgit_ecatt_data_upload.
ENDMETHOD.
METHOD get_download.
CREATE OBJECT ro_download TYPE zcl_abapgit_ecatt_data_downl.
ENDMETHOD.
METHOD get_lock_object.
rv_lock_object = 'E_ECATT_TD'.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ectc IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
ENDMETHOD.
METHOD get_object_type.
rv_object_type = cl_apl_ecatt_const=>obj_type_test_config.
ENDMETHOD.
METHOD get_upload.
CREATE OBJECT ro_upload TYPE zcl_abapgit_ecatt_config_upl.
ENDMETHOD.
METHOD get_download.
CREATE OBJECT ro_download TYPE zcl_abapgit_ecatt_config_downl.
ENDMETHOD.
METHOD get_lock_object.
rv_lock_object = 'E_ECATT_TC'.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ecsp IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
ENDMETHOD.
METHOD get_object_type.
rv_object_type = 'ECSP'.
ENDMETHOD.
METHOD get_upload.
CREATE OBJECT ro_upload TYPE zcl_abapgit_ecatt_sp_upload.
ENDMETHOD.
METHOD get_download.
CREATE OBJECT ro_download TYPE zcl_abapgit_ecatt_sp_download.
ENDMETHOD.
METHOD get_lock_object.
rv_lock_object = 'E_ECATT_SP'.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ecsd IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
ENDMETHOD.
METHOD get_object_type.
rv_object_type = cl_apl_ecatt_const=>obj_type_system_data.
ENDMETHOD.
METHOD get_upload.
CREATE OBJECT ro_upload TYPE zcl_abapgit_ecatt_system_upl.
ENDMETHOD.
METHOD get_download.
CREATE OBJECT ro_download TYPE zcl_abapgit_ecatt_system_downl.
ENDMETHOD.
METHOD get_lock_object.
rv_lock_object = 'E_ECATT_SD'.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ecatt_super IMPLEMENTATION.
METHOD clear_attributes.
DATA: lo_element TYPE REF TO if_ixml_element,
lv_object_type TYPE etobj_type.
lv_object_type = get_object_type( ).
lo_element = ci_document->find_from_name( |{ lv_object_type }| ).
lo_element->remove_attribute( |SAPRL| ).
lo_element->remove_attribute( |DOWNLOADDATE| ).
lo_element->remove_attribute( |DOWNLOADTIME| ).
ENDMETHOD.
METHOD clear_element.
DATA: lo_element TYPE REF TO if_ixml_element.
lo_element = ci_document->find_from_name( iv_name ).
IF lo_element IS BOUND.
lo_element->set_value( || ).
ENDIF.
ENDMETHOD.
METHOD clear_elements.
clear_element( EXPORTING iv_name = |FUSER|
CHANGING ci_document = ci_document ).
clear_element( EXPORTING iv_name = |FDATE|
CHANGING ci_document = ci_document ).
clear_element( EXPORTING iv_name = |LUSER|
CHANGING ci_document = ci_document ).
clear_element( EXPORTING iv_name = |LDATE|
CHANGING ci_document = ci_document ).
clear_element( EXPORTING iv_name = |LTIME|
CHANGING ci_document = ci_document ).
clear_element( EXPORTING iv_name = |TWB_RESP|
CHANGING ci_document = ci_document ).
clear_element( EXPORTING iv_name = |DEVCLASS|
CHANGING ci_document = ci_document ).
clear_element( EXPORTING iv_name = |TADIR_RESP|
CHANGING ci_document = ci_document ).
clear_element( EXPORTING iv_name = |VAR_EXT_PATH|
CHANGING ci_document = ci_document ).
ENDMETHOD.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_object_name = ms_item-obj_name.
ENDMETHOD.
METHOD deserialize_version.
DATA: ls_object TYPE etmobjects,
lo_upload TYPE REF TO cl_apl_ecatt_upload,
lv_xml TYPE xstring,
lv_text TYPE string,
li_document TYPE REF TO if_ixml_document,
lv_version TYPE string,
lx_error TYPE REF TO cx_ecatt.
lv_version = get_version_from_node( ii_version_node ).
IF lv_version IS INITIAL.
RETURN.
ENDIF.
lo_upload = get_upload( ).
li_document = cl_ixml=>create( )->create_document( ).
li_document->append_child( ii_version_node->get_first_child( ) ).
lv_xml = cl_ixml_80_20=>render_to_xstring( li_document ).
CALL METHOD lo_upload->('Z_SET_STREAM_FOR_UPLOAD')
EXPORTING
iv_xml = lv_xml.
ls_object-d_obj_name = mv_object_name.
ls_object-s_obj_type = get_object_type( ).
ls_object-d_devclass = iv_package.
ls_object-d_obj_ver = lv_version.
ls_object-d_overwrite = abap_true.
TRY.
lo_upload->upload(
CHANGING
ch_object = ls_object ).
CATCH cx_ecatt INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD get_changed_by_user.
rv_changed_by_user = ii_document->find_from_name( 'LUSER' )->get_value( ).
ENDMETHOD.
METHOD get_changed_date.
DATA: lv_changed_date_external TYPE string.
lv_changed_date_external = ii_document->find_from_name( 'LDATE' )->get_value( ).
CALL FUNCTION 'CONVERSION_EXIT_RSDAT_INPUT'
EXPORTING
input = lv_changed_date_external
IMPORTING
output = rv_changed_date
EXCEPTIONS
invalid_date = 1
OTHERS = 2.
IF sy-subrc <> 0.
RETURN.
ENDIF.
ENDMETHOD.
METHOD get_changed_time.
DATA: lv_changed_time_external TYPE string.
lv_changed_time_external = ii_document->find_from_name( 'LTIME' )->get_value( ).
CALL FUNCTION 'CONVERSION_EXIT_TIMLO_INPUT'
EXPORTING
input = lv_changed_time_external
IMPORTING
output = rv_changed_time
EXCEPTIONS
wrong_input = 1
OTHERS = 2.
IF sy-subrc <> 0.
RETURN.
ENDIF.
ENDMETHOD.
METHOD get_change_information.
DATA: li_document TYPE REF TO if_ixml_document,
lv_xml TYPE xstring,
lo_download TYPE REF TO cl_apl_ecatt_download,
lv_object_type TYPE etobj_type.
lo_download = get_download( ).
lv_object_type = get_object_type( ).
zcl_abapgit_ecatt_helper=>build_xml_of_object(
EXPORTING
im_object_name = mv_object_name
im_object_version = is_version_info-version
im_object_type = lv_object_type
io_download = lo_download
IMPORTING
ex_xml_stream = lv_xml ).
li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xml ).
rs_change_information-ldate = get_changed_date( li_document ).
rs_change_information-ltime = get_changed_time( li_document ).
rs_change_information-luser = get_changed_by_user( li_document ).
ENDMETHOD.
METHOD get_version_from_node.
TRY.
rv_version = ii_node->get_first_child(
)->get_first_child(
)->get_first_child(
)->get_first_child(
)->get_value( ).
CATCH cx_sy_ref_is_initial.
RETURN.
ENDTRY.
ENDMETHOD.
METHOD is_change_more_recent_than.
IF ( is_currently_changed-ldate > is_last_changed-ldate )
OR ( is_currently_changed-ldate = is_last_changed-ldate
AND is_currently_changed-ltime > is_last_changed-ltime ).
rv_is_change_more_recent = abap_true.
ENDIF.
ENDMETHOD.
METHOD serialize_version.
DATA: li_document TYPE REF TO if_ixml_document,
lv_xml TYPE xstring,
lo_node TYPE REF TO if_ixml_element,
lo_download TYPE REF TO cl_apl_ecatt_download,
lv_object_type TYPE etobj_type.
lo_download = get_download( ).
lv_object_type = get_object_type( ).
zcl_abapgit_ecatt_helper=>build_xml_of_object(
EXPORTING
im_object_name = mv_object_name
im_object_version = iv_version
im_object_type = lv_object_type
io_download = lo_download
IMPORTING
ex_xml_stream = lv_xml ).
li_document = cl_ixml_80_20=>parse_to_document( stream_xstring = lv_xml ).
clear_attributes(
CHANGING
ci_document = li_document ).
clear_elements(
CHANGING
ci_document = li_document ).
lo_node = li_document->create_element( co_name-version ).
lo_node->append_child( li_document->get_root_element( ) ).
ci_node->append_child( lo_node ).
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: ls_last_changed TYPE ty_last_changed,
ls_currently_changed TYPE ty_last_changed,
lt_version_info TYPE etversinfo_tabtype,
lx_error TYPE REF TO cx_ecatt,
lv_text TYPE string,
lv_object_type TYPE etobj_type.
FIELD-SYMBOLS: <ls_version_info> LIKE LINE OF lt_version_info.
TRY.
lv_object_type = get_object_type( ).
cl_apl_ecatt_object=>get_version_info_object(
EXPORTING
im_name = mv_object_name
im_obj_type = lv_object_type
IMPORTING
ex_version_info = lt_version_info ).
LOOP AT lt_version_info ASSIGNING <ls_version_info>.
ls_currently_changed = get_change_information( <ls_version_info> ).
IF is_change_more_recent_than( is_currently_changed = ls_currently_changed
is_last_changed = ls_last_changed ) = abap_true.
ls_last_changed = ls_currently_changed.
ENDIF.
ENDLOOP.
CATCH cx_ecatt INTO lx_error.
lv_text = lx_error->get_text( ).
MESSAGE lv_text TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
IF ls_last_changed-luser IS NOT INITIAL.
rv_user = ls_last_changed-luser.
ELSE.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lx_error TYPE REF TO cx_ecatt_apl,
lv_text TYPE string,
lv_object_type TYPE etobj_type.
lv_object_type = get_object_type( ).
TRY.
cl_apl_ecatt_object=>delete_object( im_obj_type = lv_object_type
im_name = mv_object_name
" we have to supply a version, so let's use the default version
" and delete them all
im_version = co_default_version
im_delete_all_versions = abap_true ).
CATCH cx_ecatt_apl INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: li_document TYPE REF TO if_ixml_document,
li_versions TYPE REF TO if_ixml_node_collection,
li_version_iterator TYPE REF TO if_ixml_node_iterator,
lo_version_node TYPE REF TO if_ixml_node.
li_document = io_xml->get_raw( ).
li_versions = li_document->get_elements_by_tag_name( depth = 0
name = co_name-version ).
li_version_iterator = li_versions->create_iterator( ).
DO.
lo_version_node = li_version_iterator->get_next( ).
IF lo_version_node IS NOT BOUND.
EXIT.
ENDIF.
deserialize_version( ii_version_node = lo_version_node
iv_package = iv_package ).
ENDDO.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_object_type TYPE etobj_type.
lv_object_type = get_object_type( ).
TRY.
rv_bool = cl_apl_ecatt_object=>existence_check_object( im_name = mv_object_name
im_version = co_default_version
im_obj_type = lv_object_type
im_exists_any_version = abap_true ).
CATCH cx_ecatt.
RETURN.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
in_new_window = abap_true
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error { sy-subrc } from RS_TOOL_ACCESS | ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA:
lt_version_info TYPE etversinfo_tabtype,
li_document TYPE REF TO if_ixml_document,
lx_error TYPE REF TO cx_ecatt,
lv_text TYPE string,
lv_object_type TYPE etobj_type.
lv_object_type = get_object_type( ).
TRY.
cl_apl_ecatt_object=>get_version_info_object(
EXPORTING
im_name = mv_object_name
im_obj_type = lv_object_type
IMPORTING
ex_version_info = lt_version_info ).
li_document = cl_ixml=>create( )->create_document( ).
serialize_versions(
EXPORTING
it_version_info = lt_version_info
CHANGING
ci_document = li_document ).
io_xml->set_raw( li_document->get_root_element( ) ).
CATCH cx_ecatt INTO lx_error.
lv_text = lx_error->get_text( ).
MESSAGE lv_text TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDMETHOD.
METHOD serialize_versions.
DATA: li_versions_node TYPE REF TO if_ixml_element.
FIELD-SYMBOLS: <ls_version_info> LIKE LINE OF it_version_info.
li_versions_node = ci_document->create_element( co_name-versions ).
IF lines( it_version_info ) > 0.
LOOP AT it_version_info ASSIGNING <ls_version_info>.
serialize_version(
EXPORTING
iv_version = <ls_version_info>-version
CHANGING
ci_node = li_versions_node ).
ENDLOOP.
ELSE.
serialize_version(
EXPORTING
iv_version = co_default_version
CHANGING
ci_node = li_versions_node ).
ENDIF.
ci_document->append_child( li_versions_node ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE seqg3-garg.
lv_object = ms_item-obj_name.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = get_lock_object( )
iv_argument = lv_object ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ecat IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
ENDMETHOD.
METHOD get_object_type.
rv_object_type = cl_apl_ecatt_const=>obj_type_test_script.
ENDMETHOD.
METHOD get_upload.
CREATE OBJECT ro_upload TYPE zcl_abapgit_ecatt_script_upl.
ENDMETHOD.
METHOD get_download.
CREATE OBJECT ro_download TYPE zcl_abapgit_ecatt_script_downl.
ENDMETHOD.
METHOD get_lock_object.
rv_lock_object = 'E_ECATT'.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_dtel IMPLEMENTATION.
METHOD deserialize_texts.
DATA: lv_name TYPE ddobjname,
ls_dd04v_tmp TYPE dd04v,
lt_i18n_langs TYPE TABLE OF langu,
lt_dd04_texts TYPE tt_dd04_texts.
FIELD-SYMBOLS: <lv_lang> LIKE LINE OF lt_i18n_langs,
<ls_dd04_text> TYPE ty_dd04_texts.
lv_name = ms_item-obj_name.
io_xml->read( EXPORTING iv_name = 'I18N_LANGS'
CHANGING cg_data = lt_i18n_langs ).
io_xml->read( EXPORTING iv_name = 'DD04_TEXTS'
CHANGING cg_data = lt_dd04_texts ).
SORT lt_i18n_langs.
SORT lt_dd04_texts BY ddlanguage. " Optimization
LOOP AT lt_i18n_langs ASSIGNING <lv_lang>.
" Data element description
ls_dd04v_tmp = is_dd04v.
READ TABLE lt_dd04_texts ASSIGNING <ls_dd04_text> WITH KEY ddlanguage = <lv_lang>.
IF sy-subrc > 0.
zcx_abapgit_exception=>raise( |DD04_TEXTS cannot find lang { <lv_lang> } in XML| ).
ENDIF.
MOVE-CORRESPONDING <ls_dd04_text> TO ls_dd04v_tmp.
CALL FUNCTION 'DDIF_DTEL_PUT'
EXPORTING
name = lv_name
dd04v_wa = ls_dd04v_tmp
EXCEPTIONS
dtel_not_found = 1
name_inconsistent = 2
dtel_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_DTEL_PUT @TEXTS' ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD serialize_texts.
DATA: lv_name TYPE ddobjname,
lv_index TYPE i,
ls_dd04v TYPE dd04v,
lt_dd04_texts TYPE tt_dd04_texts,
lt_i18n_langs TYPE TABLE OF langu.
FIELD-SYMBOLS: <lv_lang> LIKE LINE OF lt_i18n_langs,
<ls_dd04_text> TYPE ty_dd04_texts.
lv_name = ms_item-obj_name.
" Collect additional languages, skip master lang - it was serialized already
SELECT DISTINCT ddlanguage AS langu INTO TABLE lt_i18n_langs
FROM dd04v
WHERE rollname = lv_name
AND ddlanguage <> mv_language. "#EC CI_SUBRC
LOOP AT lt_i18n_langs ASSIGNING <lv_lang>.
lv_index = sy-tabix.
CALL FUNCTION 'DDIF_DTEL_GET'
EXPORTING
name = lv_name
langu = <lv_lang>
IMPORTING
dd04v_wa = ls_dd04v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0 OR ls_dd04v-ddlanguage IS INITIAL.
DELETE lt_i18n_langs INDEX lv_index. " Don't save this lang
CONTINUE.
ENDIF.
APPEND INITIAL LINE TO lt_dd04_texts ASSIGNING <ls_dd04_text>.
MOVE-CORRESPONDING ls_dd04v TO <ls_dd04_text>.
ENDLOOP.
SORT lt_i18n_langs ASCENDING.
SORT lt_dd04_texts BY ddlanguage ASCENDING.
IF lines( lt_i18n_langs ) > 0.
io_xml->add( iv_name = 'I18N_LANGS'
ig_data = lt_i18n_langs ).
io_xml->add( iv_name = 'DD04_TEXTS'
ig_data = lt_dd04_texts ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE as4user FROM dd04l INTO rv_user
WHERE rollname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objname TYPE rsedd0-ddobjname.
lv_objname = ms_item-obj_name.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = abap_true
objname = lv_objname
objtype = 'E'
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, DTEL' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_dd04v TYPE dd04v,
lv_name TYPE ddobjname,
ls_tpara TYPE tpara.
io_xml->read( EXPORTING iv_name = 'DD04V'
CHANGING cg_data = ls_dd04v ).
io_xml->read( EXPORTING iv_name = 'TPARA'
CHANGING cg_data = ls_tpara ).
corr_insert( iv_package ).
lv_name = ms_item-obj_name. " type conversion
CALL FUNCTION 'DDIF_DTEL_PUT'
EXPORTING
name = lv_name
dd04v_wa = ls_dd04v
EXCEPTIONS
dtel_not_found = 1
name_inconsistent = 2
dtel_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_DTEL_PUT' ).
ENDIF.
deserialize_texts( io_xml = io_xml
is_dd04v = ls_dd04v ).
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_rollname TYPE dd04l-rollname.
SELECT SINGLE rollname FROM dd04l INTO lv_rollname
WHERE rollname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA: lv_date TYPE dats,
lv_time TYPE tims.
SELECT SINGLE as4date as4time FROM dd04l
INTO (lv_date, lv_time)
WHERE rollname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
jump_se11( iv_radio = 'RSRD1-DDTYPE'
iv_field = 'RSRD1-DDTYPE_VAL' ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_name TYPE ddobjname,
ls_dd04v TYPE dd04v,
ls_tpara TYPE tpara.
lv_name = ms_item-obj_name.
SELECT SINGLE * FROM dd04l
INTO CORRESPONDING FIELDS OF ls_dd04v
WHERE rollname = lv_name
AND as4local = 'A'
AND as4vers = '0000'.
IF sy-subrc <> 0 OR ls_dd04v IS INITIAL.
zcx_abapgit_exception=>raise( 'Not found in DD04L' ).
ENDIF.
SELECT SINGLE * FROM dd04t
INTO CORRESPONDING FIELDS OF ls_dd04v
WHERE rollname = lv_name
AND ddlanguage = mv_language
AND as4local = 'A'
AND as4vers = '0000'.
IF NOT ls_dd04v-memoryid IS INITIAL.
SELECT SINGLE tpara~paramid tparat~partext
FROM tpara LEFT JOIN tparat
ON tparat~paramid = tpara~paramid AND
tparat~sprache = mv_language
INTO ls_tpara
WHERE tpara~paramid = ls_dd04v-memoryid. "#EC CI_BUFFJOIN
ENDIF.
CLEAR: ls_dd04v-as4user,
ls_dd04v-as4date,
ls_dd04v-as4time.
IF ls_dd04v-refkind = 'D'.
CLEAR: ls_dd04v-datatype,
ls_dd04v-leng,
ls_dd04v-decimals,
ls_dd04v-outputlen,
ls_dd04v-valexi,
ls_dd04v-lowercase,
ls_dd04v-signflag,
ls_dd04v-convexit,
ls_dd04v-entitytab.
ENDIF.
IF ls_dd04v-routputlen = ''.
CLEAR ls_dd04v-routputlen.
ENDIF.
IF ls_dd04v-authclass = ''.
CLEAR ls_dd04v-authclass.
ENDIF.
io_xml->add( iv_name = 'DD04V'
ig_data = ls_dd04v ).
io_xml->add( iv_name = 'TPARA'
ig_data = ls_tpara ).
serialize_texts( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESDICT'
iv_argument = |{ ms_item-obj_type }{ ms_item-obj_name }| ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_dsys IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_object = ms_item-obj_name.
mv_dokname = mv_object+4(*).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = read( )-head-tdluser.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'DSYS_SHOW'
EXPORTING
dokclass = c_dokclas
dokname = mv_dokname
EXCEPTIONS
class_unknown = 1
object_not_found = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DSYS_EDIT' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
SELECT SINGLE object FROM dokil INTO mv_object
WHERE id = c_id
AND object = mv_object. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
CALL FUNCTION 'DOCU_DEL'
EXPORTING
id = c_id
langu = mv_language
object = mv_object
typ = c_typ
EXCEPTIONS
ret_code = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DOCU_DEL' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_data TYPE ty_data.
ls_data = read( ).
CLEAR: ls_data-head-tdfuser,
ls_data-head-tdfreles,
ls_data-head-tdfdate,
ls_data-head-tdftime,
ls_data-head-tdluser,
ls_data-head-tdlreles,
ls_data-head-tdldate,
ls_data-head-tdltime.
io_xml->add( iv_name = 'DSYS'
ig_data = ls_data ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_data TYPE ty_data.
io_xml->read( EXPORTING iv_name = 'DSYS'
CHANGING cg_data = ls_data ).
CALL FUNCTION 'DOCU_UPDATE'
EXPORTING
head = ls_data-head
state = 'A'
typ = c_typ
version = c_version
TABLES
line = ls_data-lines.
tadir_insert( iv_package ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD read.
CALL FUNCTION 'DOCU_READ'
EXPORTING
id = c_id
langu = mv_language
object = mv_object
typ = c_typ
version = c_version
IMPORTING
doktitle = rs_data-doctitle
head = rs_data-head
TABLES
line = rs_data-lines.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_doma IMPLEMENTATION.
METHOD deserialize_texts.
DATA: lv_name TYPE ddobjname,
ls_dd01v_tmp TYPE dd01v,
lt_dd07v_tmp TYPE TABLE OF dd07v,
lt_i18n_langs TYPE TABLE OF langu,
lt_dd01_texts TYPE tt_dd01_texts,
lt_dd07_texts TYPE tt_dd07_texts.
FIELD-SYMBOLS: <lv_lang> LIKE LINE OF lt_i18n_langs,
<ls_dd07v> LIKE LINE OF it_dd07v,
<ls_dd01_text> LIKE LINE OF lt_dd01_texts,
<ls_dd07_text> LIKE LINE OF lt_dd07_texts.
lv_name = ms_item-obj_name.
io_xml->read( EXPORTING iv_name = 'I18N_LANGS'
CHANGING cg_data = lt_i18n_langs ).
io_xml->read( EXPORTING iv_name = 'DD01_TEXTS'
CHANGING cg_data = lt_dd01_texts ).
io_xml->read( EXPORTING iv_name = 'DD07_TEXTS'
CHANGING cg_data = lt_dd07_texts ).
SORT lt_i18n_langs.
SORT lt_dd07_texts BY ddlanguage. " Optimization
LOOP AT lt_i18n_langs ASSIGNING <lv_lang>.
" Domain description
ls_dd01v_tmp = is_dd01v.
READ TABLE lt_dd01_texts ASSIGNING <ls_dd01_text> WITH KEY ddlanguage = <lv_lang>.
IF sy-subrc > 0.
zcx_abapgit_exception=>raise( |DD01_TEXTS cannot find lang { <lv_lang> } in XML| ).
ENDIF.
MOVE-CORRESPONDING <ls_dd01_text> TO ls_dd01v_tmp.
" Domain values
lt_dd07v_tmp = it_dd07v.
LOOP AT lt_dd07v_tmp ASSIGNING <ls_dd07v>.
READ TABLE lt_dd07_texts ASSIGNING <ls_dd07_text>
WITH KEY ddlanguage = <lv_lang> valpos = <ls_dd07v>-valpos.
CHECK sy-subrc = 0. " ! no translation -> master translation remain (maybe not OK)
MOVE-CORRESPONDING <ls_dd07_text> TO <ls_dd07v>.
DELETE lt_dd07_texts INDEX sy-tabix. " Optimization
ENDLOOP.
CALL FUNCTION 'DDIF_DOMA_PUT'
EXPORTING
name = lv_name
dd01v_wa = ls_dd01v_tmp
TABLES
dd07v_tab = lt_dd07v_tmp
EXCEPTIONS
doma_not_found = 1
name_inconsistent = 2
doma_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_DOMA_PUT @TEXTS' ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD serialize_texts.
DATA: lv_name TYPE ddobjname,
lv_index TYPE i,
ls_dd01v TYPE dd01v,
lt_dd07v TYPE TABLE OF dd07v,
lt_i18n_langs TYPE TABLE OF langu,
lt_dd01_texts TYPE tt_dd01_texts,
lt_dd07_texts TYPE tt_dd07_texts.
FIELD-SYMBOLS: <lv_lang> LIKE LINE OF lt_i18n_langs,
<ls_dd07v> LIKE LINE OF lt_dd07v,
<ls_dd01_text> LIKE LINE OF lt_dd01_texts,
<ls_dd07_text> LIKE LINE OF lt_dd07_texts.
lv_name = ms_item-obj_name.
" Collect additional languages, skip master lang - it was serialized already
SELECT DISTINCT ddlanguage AS langu INTO TABLE lt_i18n_langs
FROM dd01v
WHERE domname = lv_name
AND ddlanguage <> mv_language. "#EC CI_SUBRC
LOOP AT lt_i18n_langs ASSIGNING <lv_lang>.
lv_index = sy-tabix.
CALL FUNCTION 'DDIF_DOMA_GET'
EXPORTING
name = lv_name
langu = <lv_lang>
IMPORTING
dd01v_wa = ls_dd01v
TABLES
dd07v_tab = lt_dd07v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0 OR ls_dd01v-ddlanguage IS INITIAL.
DELETE lt_i18n_langs INDEX lv_index. " Don't save this lang
CONTINUE.
ENDIF.
APPEND INITIAL LINE TO lt_dd01_texts ASSIGNING <ls_dd01_text>.
MOVE-CORRESPONDING ls_dd01v TO <ls_dd01_text>.
LOOP AT lt_dd07v ASSIGNING <ls_dd07v>.
APPEND INITIAL LINE TO lt_dd07_texts ASSIGNING <ls_dd07_text>.
MOVE-CORRESPONDING <ls_dd07v> TO <ls_dd07_text>.
ENDLOOP.
ENDLOOP.
SORT lt_i18n_langs ASCENDING.
SORT lt_dd01_texts BY ddlanguage ASCENDING.
SORT lt_dd07_texts BY valpos ASCENDING ddlanguage ASCENDING.
IF lines( lt_i18n_langs ) > 0.
io_xml->add( iv_name = 'I18N_LANGS'
ig_data = lt_i18n_langs ).
io_xml->add( iv_name = 'DD01_TEXTS'
ig_data = lt_dd01_texts ).
io_xml->add( iv_name = 'DD07_TEXTS'
ig_data = lt_dd07_texts ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE as4user FROM dd01l INTO rv_user
WHERE domname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_objname TYPE rsedd0-ddobjname.
lv_objname = ms_item-obj_name.
TRY.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = abap_true
objname = lv_objname
objtype = 'D'
no_ask_delete_append = abap_true
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, DOMA' ).
ENDIF.
CATCH cx_sy_dyn_call_param_not_found.
CALL FUNCTION 'RS_DD_DELETE_OBJ'
EXPORTING
no_ask = abap_true
objname = lv_objname
objtype = 'D'
EXCEPTIONS
not_executed = 1
object_not_found = 2
object_not_specified = 3
permission_failure = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_DD_DELETE_OBJ, DOMA' ).
ENDIF.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_name TYPE ddobjname,
ls_dd01v TYPE dd01v,
lt_dd07v TYPE TABLE OF dd07v.
io_xml->read( EXPORTING iv_name = 'DD01V'
CHANGING cg_data = ls_dd01v ).
io_xml->read( EXPORTING iv_name = 'DD07V_TAB'
CHANGING cg_data = lt_dd07v ).
corr_insert( iv_package ).
lv_name = ms_item-obj_name. " type conversion
CALL FUNCTION 'DDIF_DOMA_PUT'
EXPORTING
name = lv_name
dd01v_wa = ls_dd01v
TABLES
dd07v_tab = lt_dd07v
EXCEPTIONS
doma_not_found = 1
name_inconsistent = 2
doma_inconsistent = 3
put_failure = 4
put_refused = 5
OTHERS = 6.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DDIF_DOMA_PUT' ).
ENDIF.
deserialize_texts( io_xml = io_xml
is_dd01v = ls_dd01v
it_dd07v = lt_dd07v ).
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_domname TYPE dd01l-domname.
SELECT SINGLE domname FROM dd01l INTO lv_domname
WHERE domname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA: lv_date TYPE dats,
lv_time TYPE tims.
SELECT SINGLE as4date as4time FROM dd01l
INTO (lv_date, lv_time)
WHERE domname = ms_item-obj_name
AND as4local = 'A'
AND as4vers = '0000'.
rv_changed = check_timestamp(
iv_timestamp = iv_timestamp
iv_date = lv_date
iv_time = lv_time ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
jump_se11( iv_radio = 'RSRD1-DOMA'
iv_field = 'RSRD1-DOMA_VAL' ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_name TYPE ddobjname,
ls_dd01v TYPE dd01v,
lv_masklen TYPE c LENGTH 4,
lt_dd07v TYPE TABLE OF dd07v.
lv_name = ms_item-obj_name.
CALL FUNCTION 'DDIF_DOMA_GET'
EXPORTING
name = lv_name
langu = mv_language
IMPORTING
dd01v_wa = ls_dd01v
TABLES
dd07v_tab = lt_dd07v
EXCEPTIONS
illegal_input = 1
OTHERS = 2.
IF sy-subrc <> 0 OR ls_dd01v IS INITIAL.
zcx_abapgit_exception=>raise( 'error from DDIF_DOMA_GET' ).
ENDIF.
CLEAR: ls_dd01v-as4user,
ls_dd01v-as4date,
ls_dd01v-as4time.
IF ls_dd01v-authclass = ''.
CLEAR ls_dd01v-authclass.
ENDIF.
lv_masklen = ls_dd01v-masklen.
IF lv_masklen = '' OR NOT lv_masklen CO '0123456789'.
CLEAR ls_dd01v-masklen.
ENDIF.
SORT lt_dd07v BY
valpos ASCENDING
ddlanguage ASCENDING.
io_xml->add( iv_name = 'DD01V'
ig_data = ls_dd01v ).
io_xml->add( iv_name = 'DD07V_TAB'
ig_data = lt_dd07v ).
serialize_texts( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESDICT'
iv_argument = |{ ms_item-obj_type }{ ms_item-obj_name }| ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_docv IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = read( )-head-tdluser.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD read.
DATA: lv_object TYPE dokhl-object,
lv_id TYPE dokhl-id.
lv_id = ms_item-obj_name(2).
lv_object = ms_item-obj_name+2.
CALL FUNCTION 'DOCU_READ'
EXPORTING
id = lv_id
langu = mv_language
object = lv_object
typ = c_typ
version = c_version
IMPORTING
doktitle = rs_data-doctitle
head = rs_data-head
TABLES
line = rs_data-lines.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_id TYPE dokhl-id,
lv_object TYPE dokhl-object.
lv_id = ms_item-obj_name(2).
lv_object = ms_item-obj_name+2.
SELECT SINGLE id FROM dokil INTO lv_id
WHERE id = lv_id
AND object = lv_object. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( 'todo, jump DOCV' ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_id TYPE dokhl-id,
lv_object TYPE dokhl-object.
lv_id = ms_item-obj_name(2).
lv_object = ms_item-obj_name+2.
CALL FUNCTION 'DOCU_DEL'
EXPORTING
id = lv_id
langu = mv_language
object = lv_object
typ = c_typ
EXCEPTIONS
ret_code = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DOCU_DEL' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_data TYPE ty_data.
io_xml->read( EXPORTING iv_name = c_name
CHANGING cg_data = ls_data ).
CALL FUNCTION 'DOCU_UPDATE'
EXPORTING
head = ls_data-head
state = 'A'
typ = c_typ
version = c_version
TABLES
line = ls_data-lines.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_data TYPE ty_data.
ls_data = read( ).
CLEAR: ls_data-head-tdfuser,
ls_data-head-tdfreles,
ls_data-head-tdfdate,
ls_data-head-tdftime,
ls_data-head-tdluser,
ls_data-head-tdlreles,
ls_data-head-tdldate,
ls_data-head-tdltime.
io_xml->add( iv_name = c_name
ig_data = ls_data ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_doct IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD read.
DATA: lv_object TYPE dokhl-object.
lv_object = ms_item-obj_name.
CALL FUNCTION 'DOCU_READ'
EXPORTING
id = c_id
langu = mv_language
object = lv_object
typ = c_typ
version = c_version
IMPORTING
doktitle = rs_data-doctitle
head = rs_data-head
TABLES
line = rs_data-lines.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = read( )-head-tdluser.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_id TYPE dokil-id,
lv_object TYPE dokhl-object.
lv_object = ms_item-obj_name.
SELECT SINGLE id FROM dokil INTO lv_id
WHERE id = c_id
AND object = lv_object. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: ls_dokentry TYPE dokentry,
ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
" We need to modify dokentry directly, otherwise
" Batch Input on SE61 wouldn't work because it stores
" the last seen Document Class in this table. There's
" no standard function to do this. SE61 does this
" directly in its dialog modules
ls_dokentry-username = sy-uname.
ls_dokentry-langu = sy-langu.
ls_dokentry-class = c_id.
MODIFY dokentry FROM ls_dokentry.
ls_bcdata-program = 'SAPMSDCU'.
ls_bcdata-dynpro = '0100'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'RSDCU-OBJECT7'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=SHOW'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
STARTING NEW TASK 'GIT'
EXPORTING
tcode = 'SE61'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, DOCT' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_object TYPE dokhl-object.
lv_object = ms_item-obj_name.
CALL FUNCTION 'DOCU_DEL'
EXPORTING
id = c_id
langu = mv_language
object = lv_object
typ = c_typ
EXCEPTIONS
ret_code = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from DOCU_DEL' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_data TYPE ty_data.
io_xml->read( EXPORTING iv_name = c_name
CHANGING cg_data = ls_data ).
CALL FUNCTION 'DOCU_UPDATE'
EXPORTING
head = ls_data-head
state = 'A'
typ = c_typ
version = c_version
TABLES
line = ls_data-lines.
tadir_insert( iv_package ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_data TYPE ty_data.
ls_data = read( ).
CLEAR: ls_data-head-tdfuser,
ls_data-head-tdfreles,
ls_data-head-tdfdate,
ls_data-head-tdftime,
ls_data-head-tdluser,
ls_data-head-tdlreles,
ls_data-head-tdldate,
ls_data-head-tdltime.
io_xml->add( iv_name = c_name
ig_data = ls_data ).
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_DIAL IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_bcdata TYPE bdcdata,
lt_bcdata TYPE STANDARD TABLE OF bdcdata.
ls_bcdata-program = 'SAPMSDIA'.
ls_bcdata-dynpro = '1010'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'DIAPAR-DNAM'.
ls_bcdata-fval = ms_item-obj_name.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'RS38L-PARM'.
ls_bcdata-fval = abap_true.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=DELF'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-program = 'SAPLSPO1'.
ls_bcdata-dynpro = '0100'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=YES'.
APPEND ls_bcdata TO lt_bcdata.
ls_bcdata-program = 'SAPMSDIA'.
ls_bcdata-dynpro = '1010'.
ls_bcdata-dynbegin = 'X'.
APPEND ls_bcdata TO lt_bcdata.
CLEAR ls_bcdata.
ls_bcdata-fnam = 'BDC_OKCODE'.
ls_bcdata-fval = '=BACK'.
APPEND ls_bcdata TO lt_bcdata.
CALL FUNCTION 'ABAP4_CALL_TRANSACTION'
EXPORTING
tcode = 'SE35'
mode_val = 'E'
TABLES
using_tab = lt_bcdata
EXCEPTIONS
OTHERS = 1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from ABAP4_CALL_TRANSACTION, SE35' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_dialog_module TYPE ty_dialog_module.
io_xml->read(
EXPORTING
iv_name = 'DIAL'
CHANGING
cg_data = ls_dialog_module ).
CALL FUNCTION 'RS_DIALOG_CREATE'
EXPORTING
dialogname = ls_dialog_module-tdct-dnam
dynpronumber = ls_dialog_module-tdct-dynr
programname = ls_dialog_module-tdct-prog
suppress_corr_check = abap_false
TABLES
dia_par = ls_dialog_module-dia_pars
EXCEPTIONS
dialog_already_exists = 1
invalid_name = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error deserializing dialogmodule { ms_item-obj_name }| ).
ENDIF.
" It seems that there's no API for diapar, therefore we manipulate it directly
INSERT diapar FROM TABLE ls_dialog_module-dia_pars.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_tdct TYPE tdct.
ls_tdct = _read_tdct( ).
rv_bool = boolc( ls_tdct IS NOT INITIAL ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lv_objectname TYPE tdct-dnam.
lv_objectname = ms_item-obj_name.
CALL FUNCTION 'RS_DIALOG_SHOW'
EXPORTING
objectname = lv_objectname
type = 'VW'
EXCEPTIONS
object_not_found = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from RS_DIALOG_SHOW, DIAL| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_dialog_module TYPE ty_dialog_module.
ls_dialog_module-tdct = _read_tdct( ).
SELECT * FROM diapar
INTO TABLE ls_dialog_module-dia_pars
WHERE dnam = ls_dialog_module-tdct-dnam.
io_xml->add( iv_name = 'DIAL'
ig_data = ls_dialog_module ).
ENDMETHOD.
METHOD _read_tdct.
DATA: lv_dnam TYPE tdct-dnam.
lv_dnam = ms_item-obj_name.
SELECT SINGLE * FROM tdct
INTO rs_tdct
WHERE dnam = lv_dnam.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_devc IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_local_devclass = is_item-devclass.
ENDMETHOD.
METHOD get_package.
IF me->zif_abapgit_object~exists( ) = abap_true.
ri_package = load_package( mv_local_devclass ).
ENDIF.
ENDMETHOD.
METHOD is_empty.
DATA: lv_object_name TYPE tadir-obj_name,
lt_subpackages TYPE zif_abapgit_sap_package=>ty_devclass_tt.
lt_subpackages = zcl_abapgit_factory=>get_sap_package( iv_package_name )->list_subpackages( ).
IF lines( lt_subpackages ) > 0.
rv_is_empty = abap_false.
RETURN.
ENDIF.
SELECT SINGLE obj_name
FROM tadir
INTO lv_object_name
WHERE pgmid = 'R3TR'
AND NOT ( object = 'DEVC' AND obj_name = iv_package_name )
AND devclass = iv_package_name.
rv_is_empty = boolc( sy-subrc <> 0 ).
ENDMETHOD.
METHOD load_package.
cl_package_factory=>load_package(
EXPORTING
i_package_name = iv_package_name
i_force_reload = abap_true
IMPORTING
e_package = ri_package
EXCEPTIONS
object_not_existing = 1
unexpected_error = 2
intern_err = 3
no_access = 4
object_locked_and_modified = 5
OTHERS = 6 ).
IF sy-subrc = 1.
RETURN.
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD set_lock.
DATA: lv_changeable TYPE abap_bool.
ii_package->get_changeable( IMPORTING e_changeable = lv_changeable ).
IF lv_changeable <> iv_lock.
ii_package->set_changeable(
EXPORTING
i_changeable = iv_lock
EXCEPTIONS
object_locked_by_other_user = 1
permission_failure = 2
object_already_changeable = 3
object_already_unlocked = 4
object_just_created = 5
object_deleted = 6
object_modified = 7
object_not_existing = 8
object_invalid = 9
unexpected_error = 10
OTHERS = 11 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDIF.
ii_package->set_permissions_changeable(
EXPORTING
i_changeable = iv_lock
EXCEPTIONS
object_already_changeable = 1
object_already_unlocked = 2
object_locked_by_other_user = 3
object_modified = 4
object_just_created = 5
object_deleted = 6
permission_failure = 7
object_invalid = 8
unexpected_error = 9
OTHERS = 10 ).
IF ( sy-subrc = 1 AND iv_lock = abap_true ) OR ( sy-subrc = 2 AND iv_lock = abap_false ).
" There's no getter to find out beforehand...
ELSEIF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD update_pinf_usages.
DATA: lt_current_permissions TYPE tpak_permission_to_use_list,
li_usage TYPE REF TO if_package_permission_to_use,
ls_data_sign TYPE scomppsign,
ls_add_permission_data TYPE pkgpermdat,
lt_handled TYPE SORTED TABLE OF i WITH UNIQUE KEY table_line.
FIELD-SYMBOLS: <ls_usage_data> LIKE LINE OF it_usage_data.
" Get the current permissions
ii_package->get_permissions_to_use(
IMPORTING
e_permissions = lt_current_permissions
EXCEPTIONS
object_invalid = 1
unexpected_error = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ls_data_sign-err_sever = abap_true.
" New permissions
LOOP AT it_usage_data ASSIGNING <ls_usage_data>.
READ TABLE lt_current_permissions
WITH KEY table_line->package_interface_name = <ls_usage_data>-intf_name
INTO li_usage.
IF sy-subrc = 0 AND li_usage IS BOUND.
INSERT sy-tabix INTO TABLE lt_handled.
" Permission already exists, update attributes
li_usage->set_all_attributes(
EXPORTING
i_permission_data = <ls_usage_data>
i_data_sign = ls_data_sign
EXCEPTIONS
object_not_changeable = 1
object_invalid = 2
intern_err = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ELSE.
" Permission does not exist yet, add it
MOVE-CORRESPONDING <ls_usage_data> TO ls_add_permission_data.
ii_package->add_permission_to_use(
EXPORTING
i_pkg_permission_data = ls_add_permission_data
EXCEPTIONS
object_not_changeable = 1
object_access_error = 2
object_already_existing = 3
object_invalid = 4
unexpected_error = 5
OTHERS = 6 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDIF.
FREE li_usage.
ENDLOOP.
" Delete missing usages
LOOP AT lt_current_permissions INTO li_usage.
READ TABLE lt_handled WITH TABLE KEY table_line = sy-tabix TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
CONTINUE.
ENDIF.
li_usage->delete(
EXCEPTIONS
object_not_changeable = 1
object_invalid = 2
intern_err = 4
OTHERS = 5 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = get_package( )->changed_by.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: li_package TYPE REF TO if_package,
lv_package TYPE devclass.
" Package deletion is a bit tricky. A package can only be deleted if there are no objects
" contained in it. This includes subpackages, so first the leaf packages need to be deleted.
" Unfortunately deleted objects that are still contained in an unreleased transport request
" also count towards the contained objects counter.
" -> Currently we delete only empty packages
"
" If objects are deleted, the TADIR entry is deleted when the transport request is released.
" So before we can delete the package, the transport which deletes the objects
" in the package has to be released.
lv_package = ms_item-obj_name.
IF is_empty( lv_package ) = abap_true.
li_package = load_package( lv_package ).
IF li_package IS NOT BOUND.
RETURN.
ENDIF.
TRY.
CALL METHOD li_package->('SET_CHANGEABLE')
EXPORTING
i_changeable = abap_true
i_suppress_dialog = abap_true " Parameter missing in 702
EXCEPTIONS
object_locked_by_other_user = 1
permission_failure = 2
object_already_changeable = 3
object_already_unlocked = 4
object_just_created = 5
object_deleted = 6
object_modified = 7
object_not_existing = 8
object_invalid = 9
unexpected_error = 10
OTHERS = 11.
CATCH cx_root.
li_package->set_changeable(
EXPORTING
i_changeable = abap_true
EXCEPTIONS
object_locked_by_other_user = 1
permission_failure = 2
object_already_changeable = 3
object_already_unlocked = 4
object_just_created = 5
object_deleted = 6
object_modified = 7
object_not_existing = 8
object_invalid = 9
unexpected_error = 10
OTHERS = 11 ).
ENDTRY.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
TRY.
CALL METHOD li_package->('DELETE')
EXPORTING
i_suppress_dialog = abap_true " Parameter missing in 702
EXCEPTIONS
object_not_empty = 1
object_not_changeable = 2
object_invalid = 3
intern_err = 4
OTHERS = 5.
CATCH cx_root.
li_package->delete(
EXCEPTIONS
object_not_empty = 1
object_not_changeable = 2
object_invalid = 3
intern_err = 4
OTHERS = 5 ).
ENDTRY.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
li_package->save(
EXPORTING
i_suppress_dialog = abap_true
EXCEPTIONS
object_invalid = 1
object_not_changeable = 2
cancelled_in_corr = 3
permission_failure = 4
unexpected_error = 5
intern_err = 6
OTHERS = 7 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: li_package TYPE REF TO if_package,
ls_package_data TYPE scompkdtln,
ls_data_sign TYPE scompksign,
lt_usage_data TYPE scomppdata,
ls_save_sign TYPE paksavsign.
FIELD-SYMBOLS: <ls_usage_data> TYPE scomppdtln.
mv_local_devclass = iv_package.
io_xml->read(
EXPORTING
iv_name = 'DEVC'
CHANGING
cg_data = ls_package_data ).
li_package = get_package( ).
" Swap out repository package name with the local installation package name
ls_package_data-devclass = mv_local_devclass.
ls_package_data-pdevclass = li_package->transport_layer.
" Parent package is not changed. Assume the folder logic already created the package and set
" the hierarchy before.
CLEAR ls_package_data-parentcl.
ls_data_sign-ctext = abap_true.
ls_data_sign-as4user = abap_true.
ls_data_sign-pdevclass = abap_true.
ls_data_sign-comp_posid = abap_true.
ls_data_sign-component = abap_true.
ls_data_sign-perminher = abap_true.
ls_data_sign-intfprefx = abap_true.
ls_data_sign-packtype = abap_true.
ls_data_sign-restricted = abap_true.
ls_data_sign-mainpack = abap_true.
ls_data_sign-srv_check = abap_true.
ls_data_sign-cli_check = abap_true.
ls_data_sign-ext_alias = abap_true.
ls_data_sign-project_guid = abap_true.
ls_data_sign-project_id = abap_true.
ls_data_sign-project_passdown = abap_true.
IF ls_package_data-ctext IS INITIAL.
ls_package_data-ctext = mv_local_devclass.
ENDIF.
IF ls_package_data-dlvunit IS INITIAL.
ls_package_data-dlvunit = 'HOME'.
ENDIF.
ls_package_data-as4user = cl_abap_syst=>get_user_name( ).
IF li_package IS BOUND.
" Package already exists, change it
set_lock( ii_package = li_package iv_lock = abap_true ).
li_package->set_all_attributes(
EXPORTING
i_package_data = ls_package_data
i_data_sign = ls_data_sign
EXCEPTIONS
object_not_changeable = 1
object_deleted = 2
object_invalid = 3
short_text_missing = 4
author_not_existing = 5
local_package = 6
software_component_invalid = 7
layer_invalid = 8
korrflag_invalid = 9
component_not_existing = 10
component_missing = 11
authorize_failure = 12
prefix_in_use = 13
unexpected_error = 14
intern_err = 15
OTHERS = 18 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ELSE.
" Package does not exist yet, create it
" This shouldn't really happen, because the folder logic initially creates the packages.
cl_package_factory=>create_new_package(
IMPORTING
e_package = li_package
CHANGING
c_package_data = ls_package_data
EXCEPTIONS
object_already_existing = 1
object_just_created = 2
not_authorized = 3
wrong_name_prefix = 4
undefined_name = 5
reserved_local_name = 6
invalid_package_name = 7
short_text_missing = 8
software_component_invalid = 9
layer_invalid = 10
author_not_existing = 11
component_not_existing = 12
component_missing = 13
prefix_in_use = 14
unexpected_error = 15
intern_err = 16
no_access = 17
OTHERS = 22 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDIF.
" Load package interface usages
TRY.
io_xml->read(
EXPORTING
iv_name = 'PERMISSION'
CHANGING
cg_data = lt_usage_data ).
CATCH zcx_abapgit_exception ##NO_HANDLER.
" No permissions saved
ENDTRY.
LOOP AT lt_usage_data ASSIGNING <ls_usage_data>.
<ls_usage_data>-client_pak = mv_local_devclass.
ENDLOOP.
update_pinf_usages( ii_package = li_package
it_usage_data = lt_usage_data ).
ls_save_sign-pack = ls_save_sign-permis = ls_save_sign-elems = ls_save_sign-interf = abap_true.
li_package->save_generic(
EXPORTING
i_save_sign = ls_save_sign
EXCEPTIONS
cancelled_in_corr = 1
permission_failure = 2
object_not_changeable = 3
object_invalid = 4
OTHERS = 5 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
set_lock( ii_package = li_package iv_lock = abap_false ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
" Check remote package if deserialize has not been called before this
IF mv_local_devclass IS INITIAL.
rv_bool = abap_false.
ELSE.
cl_package_helper=>check_package_existence(
EXPORTING
i_package_name = mv_local_devclass
IMPORTING
e_package_exists = rv_bool
EXCEPTIONS
intern_err = 1
OTHERS = 2 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_object TYPE eqegraarg.
lv_object = |DV{ ms_item-obj_name }|.
OVERLAY lv_object WITH ' '.
lv_object = lv_object && '*'.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'EEUDB'
iv_argument = lv_object ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'DEVC'
in_new_window = abap_true
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_package_data TYPE scompkdtln,
li_package TYPE REF TO if_package,
lt_intf_usages TYPE tpak_permission_to_use_list,
lt_usage_data TYPE scomppdata,
ls_usage_data TYPE scomppdtln,
li_usage TYPE REF TO if_package_permission_to_use.
FIELD-SYMBOLS: <lg_field> TYPE any.
li_package = get_package( ).
IF li_package IS NOT BOUND.
zcx_abapgit_exception=>raise( |Could not find package to serialize.| ).
ENDIF.
li_package->get_all_attributes(
IMPORTING
e_package_data = ls_package_data
EXCEPTIONS
object_invalid = 1
package_deleted = 2
intern_err = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
CLEAR: ls_package_data-devclass,
ls_package_data-parentcl.
" Clear administrative data to prevent diffs
CLEAR: ls_package_data-created_by,
ls_package_data-created_on,
ls_package_data-changed_by,
ls_package_data-changed_on,
ls_package_data-as4user.
" Clear text descriptions that might be localized
CLEAR: ls_package_data-comp_text,
ls_package_data-dlvu_text,
ls_package_data-layer_text.
ASSIGN COMPONENT 'TRANSLATION_DEPTH_TEXT'
OF STRUCTURE ls_package_data
TO <lg_field>.
IF sy-subrc = 0.
CLEAR: <lg_field>.
ENDIF.
ASSIGN COMPONENT 'TRANSLATION_GRAPH_DEPTH_TEXT'
OF STRUCTURE ls_package_data
TO <lg_field>.
IF sy-subrc = 0.
CLEAR: <lg_field>.
ENDIF.
" Clear things related to local installation package
CLEAR: ls_package_data-namespace,
ls_package_data-dlvunit,
ls_package_data-pdevclass.
" Not usable on customer systems
ASSIGN COMPONENT 'TRANSLATION_DEPTH'
OF STRUCTURE ls_package_data
TO <lg_field>.
IF sy-subrc = 0.
CLEAR: <lg_field>.
ENDIF.
ASSIGN COMPONENT 'TRANSLATION_GRAPH_DEPTH'
OF STRUCTURE ls_package_data
TO <lg_field>.
IF sy-subrc = 0.
CLEAR: <lg_field>.
ENDIF.
CLEAR: ls_package_data-korrflag.
io_xml->add( iv_name = 'DEVC' ig_data = ls_package_data ).
" Save package interface usages
li_package->get_permissions_to_use(
IMPORTING
e_permissions = lt_intf_usages
EXCEPTIONS
object_invalid = 1
unexpected_error = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
LOOP AT lt_intf_usages INTO li_usage.
li_usage->get_all_attributes(
IMPORTING
e_permission_data = ls_usage_data
EXCEPTIONS
object_invalid = 1
intern_err = 2
OTHERS = 3 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise_t100( ).
ENDIF.
CLEAR: ls_usage_data-pack_name, ls_usage_data-client_pak.
APPEND ls_usage_data TO lt_usage_data.
ENDLOOP.
IF lt_usage_data IS NOT INITIAL.
io_xml->add( iv_name = 'PERMISSION' ig_data = lt_usage_data ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_ddlx IMPLEMENTATION.
METHOD clear_field.
FIELD-SYMBOLS: <lg_field> TYPE data.
ASSIGN COMPONENT iv_fieldname
OF STRUCTURE cs_metadata
TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR: <lg_field>.
ENDMETHOD.
METHOD clear_fields.
FIELD-SYMBOLS: <lg_metadata> TYPE any.
ASSIGN COMPONENT 'METADATA'
OF STRUCTURE cs_data
TO <lg_metadata>.
ASSERT sy-subrc = 0.
clear_field( EXPORTING iv_fieldname = 'CHANGED_AT'
CHANGING cs_metadata = <lg_metadata> ).
clear_field( EXPORTING iv_fieldname = 'CHANGED_BY'
CHANGING cs_metadata = <lg_metadata> ).
clear_field( EXPORTING iv_fieldname = 'CREATED_AT'
CHANGING cs_metadata = <lg_metadata> ).
clear_field( EXPORTING iv_fieldname = 'CREATED_BY'
CHANGING cs_metadata = <lg_metadata> ).
clear_field( EXPORTING iv_fieldname = 'RESPONSIBLE'
CHANGING cs_metadata = <lg_metadata> ).
clear_field( EXPORTING iv_fieldname = 'PACKAGE_REF-NAME'
CHANGING cs_metadata = <lg_metadata> ).
clear_field( EXPORTING iv_fieldname = 'CONTAINER_REF-PACKAGE_NAME'
CHANGING cs_metadata = <lg_metadata> ).
ENDMETHOD.
METHOD get_persistence.
TRY.
IF mo_persistence IS NOT BOUND.
CREATE OBJECT mo_persistence
TYPE ('CL_DDLX_ADT_OBJECT_PERSIST').
ENDIF.
CATCH cx_root.
zcx_abapgit_exception=>raise( `DDLX not supported` ).
ENDTRY.
ri_persistence = mo_persistence.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_object_key TYPE seu_objkey,
li_data_model TYPE REF TO if_wb_object_data_model,
lv_text TYPE string,
lx_error TYPE REF TO cx_root.
lv_object_key = ms_item-obj_name.
TRY.
CREATE OBJECT li_data_model TYPE ('CL_DDLX_WB_OBJECT_DATA').
get_persistence( )->delete( p_object_key = lv_object_key
p_version = swbm_version_active ).
CATCH cx_root INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: li_data_model TYPE REF TO if_wb_object_data_model,
lr_data TYPE REF TO data,
lv_text TYPE string,
lx_error TYPE REF TO cx_root.
FIELD-SYMBOLS: <lg_data> TYPE any.
TRY.
CREATE DATA lr_data
TYPE ('CL_DDLX_WB_OBJECT_DATA=>TY_OBJECT_DATA').
ASSIGN lr_data->* TO <lg_data>.
io_xml->read(
EXPORTING
iv_name = 'DDLX'
CHANGING
cg_data = <lg_data> ).
CREATE OBJECT li_data_model
TYPE ('CL_DDLX_WB_OBJECT_DATA').
li_data_model->set_data( <lg_data> ).
get_persistence( )->save( li_data_model ).
CATCH cx_root INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_object_key TYPE seu_objkey.
lv_object_key = ms_item-obj_name.
rv_bool = abap_true.
TRY.
get_persistence( )->get( p_object_key = lv_object_key
p_version = swbm_version_active
p_existence_check_only = abap_true ).
CATCH cx_swb_exception.
rv_bool = abap_false.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
TRY.
jump_adt( i_obj_name = ms_item-obj_name
i_obj_type = ms_item-obj_type ).
CATCH zcx_abapgit_exception.
zcx_abapgit_exception=>raise( 'DDLX Jump Error' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lv_object_key TYPE seu_objkey,
li_data_model TYPE REF TO if_wb_object_data_model,
li_persistence TYPE REF TO if_wb_object_persist,
lr_data TYPE REF TO data,
lv_text TYPE string,
lx_error TYPE REF TO cx_root.
FIELD-SYMBOLS: <lg_data> TYPE any.
lv_object_key = ms_item-obj_name.
TRY.
CREATE DATA lr_data
TYPE ('CL_DDLX_WB_OBJECT_DATA=>TY_OBJECT_DATA').
ASSIGN lr_data->* TO <lg_data>.
CREATE OBJECT li_data_model
TYPE ('CL_DDLX_WB_OBJECT_DATA').
li_persistence = get_persistence( ).
li_persistence->get(
EXPORTING
p_object_key = lv_object_key
p_version = swbm_version_active
CHANGING
p_object_data = li_data_model ).
li_data_model->get_data(
IMPORTING
p_data = <lg_data> ).
clear_fields( CHANGING cs_data = <lg_data> ).
io_xml->add( iv_name = 'DDLX'
ig_data = <lg_data> ).
CATCH cx_root INTO lx_error.
lv_text = lx_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESDICT'
iv_argument = |{ ms_item-obj_type }{ ms_item-obj_name }| ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_DDLS IMPLEMENTATION.
METHOD open_adt_stob.
DATA: lr_data TYPE REF TO data.
DATA: lo_ddl TYPE REF TO object.
FIELD-SYMBOLS: <lt_ddnames> TYPE STANDARD TABLE.
FIELD-SYMBOLS: <lt_entity_view> TYPE STANDARD TABLE.
FIELD-SYMBOLS: <lg_ddnames> TYPE any.
FIELD-SYMBOLS: <lg_entity_view> TYPE any.
FIELD-SYMBOLS: <lg_ddname> TYPE any.
FIELD-SYMBOLS: <lg_ddlname> TYPE any.
TRY.
CREATE DATA lr_data TYPE ('IF_DD_DDL_TYPES=>TY_T_DDOBJ').
ASSIGN lr_data->* TO <lt_ddnames>.
CREATE DATA lr_data LIKE LINE OF <lt_ddnames>.
ASSIGN lr_data->* TO <lg_ddnames>.
CREATE DATA lr_data TYPE ('IF_DD_DDL_TYPES=>TY_T_ENTITY_OF_VIEW').
ASSIGN lr_data->* TO <lt_entity_view>.
CREATE DATA lr_data LIKE LINE OF <lt_entity_view>.
ASSIGN lr_data->* TO <lg_entity_view>.
CLEAR <lt_ddnames>.
ASSIGN COMPONENT 'NAME' OF STRUCTURE <lg_ddnames> TO <lg_ddname>.
<lg_ddname> = iv_ddls_name.
INSERT <lg_ddnames> INTO TABLE <lt_ddnames>.
CALL METHOD ('CL_DD_DDL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
handler = lo_ddl.
CALL METHOD lo_ddl->('IF_DD_DDL_HANDLER~GET_VIEWNAME_FROM_ENTITYNAME')
EXPORTING
ddnames = <lt_ddnames>
IMPORTING
view_of_entity = <lt_entity_view>.
READ TABLE <lt_entity_view> ASSIGNING <lg_entity_view> INDEX 1.
IF sy-subrc = 0.
ASSIGN COMPONENT 'DDLNAME' OF STRUCTURE <lg_entity_view> TO <lg_ddlname>.
jump_adt( i_obj_name = <lg_ddlname>
i_obj_type = 'DDLS' ).
ENDIF.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'DDLS Jump Error' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lo_ddl TYPE REF TO object,
lr_data TYPE REF TO data.
FIELD-SYMBOLS: <lg_data> TYPE any,
<lg_field> TYPE any.
CREATE DATA lr_data TYPE ('DDDDLSRCV').
ASSIGN lr_data->* TO <lg_data>.
CALL METHOD ('CL_DD_DDL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
handler = lo_ddl.
TRY.
CALL METHOD lo_ddl->('IF_DD_DDL_HANDLER~READ')
EXPORTING
name = ms_item-obj_name
get_state = 'A'
IMPORTING
ddddlsrcv_wa = <lg_data>.
ASSIGN COMPONENT 'AS4USER' OF STRUCTURE <lg_data> TO <lg_field>.
IF sy-subrc = 0.
rv_user = <lg_field>.
ENDIF.
CATCH cx_root.
ENDTRY.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_ddl TYPE REF TO object.
CALL METHOD ('CL_DD_DDL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
handler = lo_ddl.
TRY.
CALL METHOD lo_ddl->('IF_DD_DDL_HANDLER~DELETE')
EXPORTING
name = ms_item-obj_name.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'DDLS error deleting' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lo_ddl TYPE REF TO object,
lr_data TYPE REF TO data.
FIELD-SYMBOLS: <lg_data> TYPE any,
<lg_field> TYPE any.
CREATE DATA lr_data TYPE ('DDDDLSRCV').
ASSIGN lr_data->* TO <lg_data>.
io_xml->read( EXPORTING iv_name = 'DDLS'
CHANGING cg_data = <lg_data> ).
ASSIGN COMPONENT 'SOURCE' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
<lg_field> = mo_files->read_string( 'asddls' ) ##no_text.
CALL METHOD ('CL_DD_DDL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
handler = lo_ddl.
TRY.
CALL METHOD lo_ddl->('IF_DD_DDL_HANDLER~SAVE')
EXPORTING
name = ms_item-obj_name
put_state = 'N'
ddddlsrcv_wa = <lg_data>.
CALL METHOD lo_ddl->('IF_DD_DDL_HANDLER~WRITE_TADIR')
EXPORTING
objectname = ms_item-obj_name
devclass = iv_package
prid = 0.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'DDLS error writing TADIR' ).
ENDTRY.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_state TYPE objstate,
lo_ddl TYPE REF TO object.
CALL METHOD ('CL_DD_DDL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
handler = lo_ddl.
TRY.
CALL METHOD lo_ddl->('IF_DD_DDL_HANDLER~READ')
EXPORTING
name = ms_item-obj_name
get_state = 'A'
IMPORTING
got_state = lv_state.
IF lv_state IS INITIAL.
rv_bool = abap_false.
ELSE.
rv_bool = abap_true.
ENDIF.
CATCH cx_root.
rv_bool = abap_false.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lv_typename TYPE typename.
DATA: lv_ddtypekind TYPE ddtypekind.
lv_typename = ms_item-obj_name.
CALL FUNCTION 'DDIF_TYPEINFO_GET'
EXPORTING
typename = lv_typename
IMPORTING
typekind = lv_ddtypekind.
CASE lv_ddtypekind.
WHEN 'STOB'.
me->open_adt_stob( ms_item-obj_name ).
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'DDLS Jump Error' ).
ENDCASE.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_ddl TYPE REF TO object,
lr_data TYPE REF TO data,
lt_clr_comps TYPE STANDARD TABLE OF fieldname WITH DEFAULT KEY.
FIELD-SYMBOLS: <lg_data> TYPE any,
<lg_field> TYPE any,
<lv_comp> LIKE LINE OF lt_clr_comps.
CREATE DATA lr_data TYPE ('DDDDLSRCV').
ASSIGN lr_data->* TO <lg_data>.
CALL METHOD ('CL_DD_DDL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
handler = lo_ddl.
TRY.
CALL METHOD lo_ddl->('IF_DD_DDL_HANDLER~READ')
EXPORTING
name = ms_item-obj_name
get_state = 'A'
IMPORTING
ddddlsrcv_wa = <lg_data>.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'DDLS error reading' ).
ENDTRY.
APPEND 'AS4USER' TO lt_clr_comps.
APPEND 'AS4DATE' TO lt_clr_comps.
APPEND 'AS4TIME' TO lt_clr_comps.
APPEND 'ACTFLAG' TO lt_clr_comps.
APPEND 'CHGFLAG' TO lt_clr_comps.
LOOP AT lt_clr_comps ASSIGNING <lv_comp>.
ASSIGN COMPONENT <lv_comp> OF STRUCTURE <lg_data> TO <lg_field>.
IF sy-subrc = 0.
CLEAR <lg_field>.
ENDIF.
ENDLOOP.
ASSIGN COMPONENT 'SOURCE' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
mo_files->add_string( iv_ext = 'asddls'
iv_string = <lg_field> ) ##no_text.
CLEAR <lg_field>.
io_xml->add( iv_name = 'DDLS'
ig_data = <lg_data> ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ESDICT'
iv_argument = |{ ms_item-obj_type }{ ms_item-obj_name }| ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_dcls IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_dcl TYPE REF TO object.
TRY.
CALL METHOD ('CL_ACM_DCL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
ro_handler = lo_dcl.
CALL METHOD lo_dcl->('DELETE')
EXPORTING
iv_dclname = ms_item-obj_name.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'DCLS error' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lr_data TYPE REF TO data,
lo_dcl TYPE REF TO object.
FIELD-SYMBOLS: <lg_data> TYPE any,
<lg_field> TYPE any.
CREATE DATA lr_data TYPE ('ACM_S_DCLSRC').
ASSIGN lr_data->* TO <lg_data>.
io_xml->read(
EXPORTING
iv_name = 'DCLS'
CHANGING
cg_data = <lg_data> ).
ASSIGN COMPONENT 'SOURCE' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
<lg_field> = mo_files->read_string( 'asdcls' ).
TRY.
CALL METHOD ('CL_ACM_DCL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
ro_handler = lo_dcl.
CALL METHOD lo_dcl->('SAVE')
EXPORTING
iv_dclname = ms_item-obj_name
iv_put_state = 'A'
is_dclsrc = <lg_data>
iv_devclass = iv_package
iv_access_mode = 'INSERT'.
tadir_insert( iv_package ).
CATCH cx_root.
zcx_abapgit_exception=>raise( 'DCLS error' ).
ENDTRY.
zcl_abapgit_objects_activation=>add_item( ms_item ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lo_dcl TYPE REF TO object.
TRY.
CALL METHOD ('CL_ACM_DCL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
ro_handler = lo_dcl.
CALL METHOD lo_dcl->('CHECK_EXISTENCE')
EXPORTING
iv_objectname = ms_item-obj_name
RECEIVING
rv_exists = rv_bool.
CATCH cx_root.
rv_bool = abap_false.
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-ddic = abap_true.
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
TRY.
jump_adt( i_obj_name = ms_item-obj_name
i_obj_type = ms_item-obj_type ).
CATCH zcx_abapgit_exception.
zcx_abapgit_exception=>raise( 'DCLS Jump Error' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lr_data TYPE REF TO data,
lo_dcl TYPE REF TO object.
FIELD-SYMBOLS: <lg_data> TYPE any,
<lg_field> TYPE any.
CREATE DATA lr_data TYPE ('ACM_S_DCLSRC').
ASSIGN lr_data->* TO <lg_data>.
TRY.
CALL METHOD ('CL_ACM_DCL_HANDLER_FACTORY')=>('CREATE')
RECEIVING
ro_handler = lo_dcl.
CALL METHOD lo_dcl->('READ')
EXPORTING
iv_dclname = ms_item-obj_name
IMPORTING
es_dclsrc = <lg_data>.
ASSIGN COMPONENT 'AS4USER' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'AS4DATE' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'AS4TIME' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CREATED_BY' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'CREATED_DATE' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
CLEAR <lg_field>.
ASSIGN COMPONENT 'SOURCE' OF STRUCTURE <lg_data> TO <lg_field>.
ASSERT sy-subrc = 0.
mo_files->add_string( iv_ext = 'asdcls' iv_string = <lg_field> ).
CLEAR <lg_field>.
io_xml->add( iv_name = 'DCLS'
ig_data = <lg_data> ).
CATCH cx_root.
zcx_abapgit_exception=>raise( 'DCLS error' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'E_ACMDCLSRC'
iv_argument = |{ ms_item-obj_name }| ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_cus2 IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_img_attribute = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( |TODO: Jump| ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
CALL FUNCTION 'S_CUS_ATTRIBUTES_EXIST'
EXPORTING
img_attribute = mv_img_attribute
EXCEPTIONS
attributes_exists_not = 1
OTHERS = 2.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_message TYPE hier_mess.
CALL FUNCTION 'S_CUS_ATTRIBUTES_DELETE'
EXPORTING
img_attribute = mv_img_attribute
IMPORTING
message = ls_message.
IF ls_message-msgty <> 'S'.
zcx_abapgit_exception=>raise( |error from delete CUS2 { mv_img_attribute } S_CUS_ATTRIBUTES_DELETE| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_customizing_attribute TYPE ty_customizing_attribute.
CALL FUNCTION 'S_CUS_ATTRIBUTES_READ'
EXPORTING
img_attribute = mv_img_attribute
IMPORTING
attribute_header = ls_customizing_attribute-header
TABLES
attribute_title = ls_customizing_attribute-titles
attribute_countries = ls_customizing_attribute-countries
attribute_components = ls_customizing_attribute-components
attribute_components_variants = ls_customizing_attribute-components_variants.
CLEAR: ls_customizing_attribute-header-fdatetime,
ls_customizing_attribute-header-fuser,
ls_customizing_attribute-header-ldatetime,
ls_customizing_attribute-header-luser.
io_xml->add( iv_name = 'CUS2'
ig_data = ls_customizing_attribute ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_customizing_attribute TYPE ty_customizing_attribute,
ls_message TYPE hier_mess.
io_xml->read(
EXPORTING
iv_name = 'CUS2'
CHANGING
cg_data = ls_customizing_attribute ).
CALL FUNCTION 'S_CUS_ATTRIBUTES_SAVE'
EXPORTING
img_attribute = ls_customizing_attribute-header
IMPORTING
message = ls_message
TABLES
attributes_title = ls_customizing_attribute-titles
attributes_countries = ls_customizing_attribute-countries
attributes_components = ls_customizing_attribute-components.
IF ls_message-msgty <> 'S'.
zcx_abapgit_exception=>raise( |error from deserialize CUS2 { mv_img_attribute } S_CUS_ATTRIBUTES_SAVE| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_cus1 IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_customizing_activity = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( |TODO: Jump| ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
CALL FUNCTION 'S_CUS_ACTIVITY_EXIST'
EXPORTING
activity = mv_customizing_activity
EXCEPTIONS
activity_exists_not = 1
OTHERS = 2.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_message TYPE hier_mess.
CALL FUNCTION 'S_CUS_ACTIVITY_DELETE'
EXPORTING
activity = mv_customizing_activity
IMPORTING
message = ls_message.
IF ls_message-msgty <> 'S'.
zcx_abapgit_exception=>raise( |error from delete CUS1 { mv_customizing_activity } S_CUS_ACTIVITY_DELETE| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_customzing_activity TYPE ty_customzing_activity.
CALL FUNCTION 'S_CUS_ACTIVITY_READ'
EXPORTING
activity = mv_customizing_activity
IMPORTING
activity_header = ls_customzing_activity-activity_header
activity_customer_exit = ls_customzing_activity-activity_customer_exit
TABLES
activity_title = ls_customzing_activity-activity_title
objects = ls_customzing_activity-objects
objects_title = ls_customzing_activity-objects_title.
CLEAR: ls_customzing_activity-activity_header-fdatetime,
ls_customzing_activity-activity_header-fuser,
ls_customzing_activity-activity_header-ldatetime,
ls_customzing_activity-activity_header-luser.
io_xml->add( iv_name = 'CUS1'
ig_data = ls_customzing_activity ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_customzing_activity TYPE ty_customzing_activity,
ls_message TYPE hier_mess.
io_xml->read(
EXPORTING
iv_name = 'CUS1'
CHANGING
cg_data = ls_customzing_activity ).
CALL FUNCTION 'S_CUS_ACTIVITY_SAVE'
EXPORTING
activity = ls_customzing_activity-activity_header-act_id
activity_type = ls_customzing_activity-activity_header-act_type
tcode = ls_customzing_activity-activity_header-tcode
customer_exit = ls_customzing_activity-activity_customer_exit-exit_name
customer_exit_enhancement = ls_customzing_activity-activity_customer_exit-enhancement
customer_exit_implementation = ls_customzing_activity-activity_customer_exit-impl_name
IMPORTING
message = ls_message
TABLES
activity_title = ls_customzing_activity-activity_title
objects = ls_customzing_activity-objects
objects_texts = ls_customzing_activity-objects_title.
IF ls_message-msgty <> 'S'.
zcx_abapgit_exception=>raise( |error from deserialize CUS1 { mv_customizing_activity } S_CUS_ACTIVITY_SAVE| ).
ENDIF.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = ms_item-obj_name
object_class = ms_item-obj_type
mode = 'I'
global_lock = abap_true
devclass = iv_package
master_language = sy-langu
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT, CUS0' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_CUS0 IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
mv_img_activity = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_message TYPE hier_mess.
CALL FUNCTION 'S_CUS_IMG_ACTIVITY_DELETE'
EXPORTING
img_activity = mv_img_activity
IMPORTING
message = ls_message.
IF ls_message-msgty <> 'S'.
zcx_abapgit_exception=>raise( |error from delete CUS0 { mv_img_activity } S_CUS_IMG_ACTIVITY_DELETE| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_img_activity TYPE ty_img_activity,
ls_text LIKE LINE OF ls_img_activity-texts.
io_xml->read(
EXPORTING
iv_name = 'CUS0'
CHANGING
cg_data = ls_img_activity ).
READ TABLE ls_img_activity-texts INTO ls_text
WITH KEY spras = sy-langu.
CALL FUNCTION 'S_CUS_IMG_ACTIVITY_SAVE'
EXPORTING
img_activity = ls_img_activity-header-activity
i_docu = ls_img_activity-header-docu_id
i_attributes = ls_img_activity-header-attributes
i_activity = ls_img_activity-header-c_activity
i_description = ls_text
i_tcode = ls_img_activity-header-tcode.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = ms_item-obj_name
object_class = ms_item-obj_type
mode = 'I'
global_lock = abap_true
devclass = iv_package
master_language = sy-langu
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT, CUS0' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_message TYPE hier_mess.
CALL FUNCTION 'S_CUS_IMG_ACTIVITY_EXISTS'
EXPORTING
img_activity = mv_img_activity
IMPORTING
message = ls_message.
rv_bool = boolc( ls_message IS INITIAL ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( |TODO: Jump| ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_img_activity TYPE ty_img_activity.
CALL FUNCTION 'S_CUS_IMG_ACTIVITY_READ'
EXPORTING
img_activity = mv_img_activity
IMPORTING
img_activity_header = ls_img_activity-header
TABLES
img_activity_texts = ls_img_activity-texts.
CLEAR: ls_img_activity-header-fuser,
ls_img_activity-header-fdate,
ls_img_activity-header-ftime,
ls_img_activity-header-luser,
ls_img_activity-header-ldate,
ls_img_activity-header-ltime.
io_xml->add( iv_name = 'CUS0'
ig_data = ls_img_activity ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_cmpt IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
TRY.
CALL METHOD ('CL_CMP_TEMPLATE')=>('S_GET_DB_ACCESS')
RECEIVING
r_ref_db_access = mo_cmp_db.
CATCH cx_root.
ENDTRY.
mv_name = ms_item-obj_name.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lo_cmp_template TYPE REF TO object.
TRY.
CALL METHOD ('CL_CMP_TEMPLATE')=>('S_CREATE_FROM_DB')
EXPORTING
i_name = mv_name
i_version = 'A'
RECEIVING
r_ref_template = lo_cmp_template.
CALL METHOD lo_cmp_template->('IF_CMP_TEMPLATE_EDIT~GET_CHANGE_USER')
RECEIVING
r_user = rv_user.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'CMPT not supported' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_deleted TYPE abap_bool.
TRY.
CALL METHOD mo_cmp_db->('IF_CMP_TEMPLATE_DB~DELETE_TEMPLATE')
EXPORTING
i_name = mv_name
i_version = 'A'
i_flg_header = abap_true
i_flg_lines = abap_true
RECEIVING
r_flg_deleted = lv_deleted.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'CMPT not supported' ).
ENDTRY.
IF lv_deleted = abap_false.
zcx_abapgit_exception=>raise( |Error deleting CMPT { ms_item-obj_name }| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lr_template TYPE REF TO data.
FIELD-SYMBOLS: <lg_template> TYPE any.
TRY.
CREATE DATA lr_template TYPE ('IF_CMP_TEMPLATE_DB=>TYP_TEMPLATE').
ASSIGN lr_template->* TO <lg_template>.
io_xml->read(
EXPORTING
iv_name = 'CMPT'
CHANGING
cg_data = <lg_template> ).
CALL METHOD mo_cmp_db->('IF_CMP_TEMPLATE_DB~SAVE_TEMPLATE')
EXPORTING
i_template_db = <lg_template>
i_flg_header = abap_true
i_flg_lines = abap_true.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'CMPT not supported' ).
ENDTRY.
CALL FUNCTION 'RS_CORR_INSERT'
EXPORTING
object = ms_item-obj_name
object_class = ms_item-obj_type
mode = 'I'
global_lock = abap_true
devclass = iv_package
master_language = mv_language
EXCEPTIONS
cancelled = 1
permission_failure = 2
unknown_objectclass = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from RS_CORR_INSERT, CMPT' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
TRY.
CALL METHOD ('CL_CMP_TEMPLATE')=>('S_TEMPLATE_EXISTS')
EXPORTING
i_name = mv_name
i_version = 'A'
RECEIVING
r_flg_exists = rv_bool.
CATCH cx_root.
zcx_abapgit_exception=>raise( 'CMPT not supported' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from RS_TOOL_ACCESS, CMPT| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lr_template TYPE REF TO data.
FIELD-SYMBOLS: <lg_template> TYPE any.
TRY.
CREATE DATA lr_template TYPE ('IF_CMP_TEMPLATE_DB=>TYP_TEMPLATE').
ASSIGN lr_template->* TO <lg_template>.
CALL METHOD mo_cmp_db->('IF_CMP_TEMPLATE_DB~READ_TEMPLATE')
EXPORTING
i_name = |{ ms_item-obj_name }|
i_version = 'A'
RECEIVING
r_template = <lg_template>.
io_xml->add( iv_name = 'CMPT'
ig_data = <lg_template> ).
CATCH cx_root.
zcx_abapgit_exception=>raise( 'CMPT not supported' ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_clas_old IMPLEMENTATION.
METHOD constructor.
super->constructor(
is_item = is_item
iv_language = iv_language ).
mi_object_oriented_object_fct = zcl_abapgit_oo_factory=>make( ms_item-obj_type ).
ENDMETHOD.
METHOD deserialize_abap.
DATA: ls_vseoclass TYPE vseoclass,
lt_source TYPE seop_source_string,
lt_local_definitions TYPE seop_source_string,
lt_local_implementations TYPE seop_source_string,
lt_local_macros TYPE seop_source_string,
lt_test_classes TYPE seop_source_string,
lt_descriptions TYPE zif_abapgit_definitions=>ty_seocompotx_tt,
ls_class_key TYPE seoclskey.
lt_source = mo_files->read_abap( ).
lt_local_definitions = mo_files->read_abap( iv_extra = 'locals_def'
iv_error = abap_false ). "#EC NOTEXT
lt_local_implementations = mo_files->read_abap( iv_extra = 'locals_imp'
iv_error = abap_false ). "#EC NOTEXT
lt_local_macros = mo_files->read_abap( iv_extra = 'macros'
iv_error = abap_false ). "#EC NOTEXT
lt_test_classes = mo_files->read_abap( iv_extra = 'testclasses'
iv_error = abap_false ). "#EC NOTEXT
ls_class_key-clsname = ms_item-obj_name.
io_xml->read( EXPORTING iv_name = 'VSEOCLASS'
CHANGING cg_data = ls_vseoclass ).
mi_object_oriented_object_fct->create(
EXPORTING
iv_package = iv_package
CHANGING
cg_properties = ls_vseoclass ).
mi_object_oriented_object_fct->generate_locals(
is_key = ls_class_key
iv_force = seox_true
it_local_definitions = lt_local_definitions
it_local_implementations = lt_local_implementations
it_local_macros = lt_local_macros
it_local_test_classes = lt_test_classes ).
mi_object_oriented_object_fct->deserialize_source(
is_key = ls_class_key
it_source = lt_source ).
io_xml->read( EXPORTING iv_name = 'DESCRIPTIONS'
CHANGING cg_data = lt_descriptions ).
mi_object_oriented_object_fct->update_descriptions(
is_key = ls_class_key
it_descriptions = lt_descriptions ).
mi_object_oriented_object_fct->add_to_activation_list( ms_item ).
ENDMETHOD.
METHOD deserialize_docu.
DATA: lt_lines TYPE tlinetab,
lv_object TYPE dokhl-object.
io_xml->read( EXPORTING iv_name = 'LINES'
CHANGING cg_data = lt_lines ).
IF lines( lt_lines ) = 0.
RETURN.
ENDIF.
lv_object = ms_item-obj_name.
mi_object_oriented_object_fct->create_documentation(
it_lines = lt_lines
iv_object_name = lv_object
iv_language = mv_language ).
ENDMETHOD.
METHOD deserialize_sotr.
"OTR stands for Online Text Repository
DATA: lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt.
io_xml->read( EXPORTING iv_name = 'SOTR'
CHANGING cg_data = lt_sotr ).
IF lines( lt_sotr ) = 0.
RETURN.
ENDIF.
mi_object_oriented_object_fct->create_sotr(
iv_package = iv_package
it_sotr = lt_sotr ).
ENDMETHOD.
METHOD deserialize_tpool.
DATA: lv_clsname TYPE seoclsname,
lt_tpool_ext TYPE zif_abapgit_definitions=>ty_tpool_tt,
lt_tpool TYPE textpool_table.
io_xml->read( EXPORTING iv_name = 'TPOOL'
CHANGING cg_data = lt_tpool_ext ).
lt_tpool = read_tpool( lt_tpool_ext ).
IF lines( lt_tpool ) = 0.
RETURN.
ENDIF.
lv_clsname = ms_item-obj_name.
mi_object_oriented_object_fct->insert_text_pool(
iv_class_name = lv_clsname
it_text_pool = lt_tpool
iv_language = mv_language ).
ENDMETHOD.
METHOD serialize_xml.
DATA: ls_vseoclass TYPE vseoclass,
lt_tpool TYPE textpool_table,
lt_descriptions TYPE zif_abapgit_definitions=>ty_seocompotx_tt,
ls_clskey TYPE seoclskey,
lt_sotr TYPE zif_abapgit_definitions=>ty_sotr_tt,
lt_lines TYPE tlinetab.
ls_clskey-clsname = ms_item-obj_name.
"If class was deserialized with a previous versions of abapGit and current language was different
"from master language at this time, this call would return SY-LANGU as master language. To fix
"these objects, set SY-LANGU to master language temporarily.
zcl_abapgit_language=>set_current_language( mv_language ).
TRY.
ls_vseoclass = mi_object_oriented_object_fct->get_class_properties( ls_clskey ).
CLEANUP.
zcl_abapgit_language=>restore_login_language( ).
ENDTRY.
zcl_abapgit_language=>restore_login_language( ).
CLEAR: ls_vseoclass-uuid,
ls_vseoclass-author,
ls_vseoclass-createdon,
ls_vseoclass-changedby,
ls_vseoclass-changedon,
ls_vseoclass-r3release,
ls_vseoclass-chgdanyby,
ls_vseoclass-chgdanyon.
IF mv_skip_testclass = abap_true.
CLEAR ls_vseoclass-with_unit_tests.
ENDIF.
io_xml->add( iv_name = 'VSEOCLASS'
ig_data = ls_vseoclass ).
lt_tpool = mi_object_oriented_object_fct->read_text_pool(
iv_class_name = ls_clskey-clsname
iv_language = mv_language ).
io_xml->add( iv_name = 'TPOOL'
ig_data = add_tpool( lt_tpool ) ).
IF ls_vseoclass-category = seoc_category_exception.
lt_sotr = mi_object_oriented_object_fct->read_sotr( ms_item-obj_name ).
IF lines( lt_sotr ) > 0.
io_xml->add( iv_name = 'SOTR'
ig_data = lt_sotr ).
ENDIF.
ENDIF.
lt_lines = mi_object_oriented_object_fct->read_documentation(
iv_class_name = ls_clskey-clsname
iv_language = mv_language ).
IF lines( lt_lines ) > 0.
io_xml->add( iv_name = 'LINES'
ig_data = lt_lines ).
ENDIF.
lt_descriptions = mi_object_oriented_object_fct->read_descriptions( ls_clskey-clsname ).
IF lines( lt_descriptions ) > 0.
io_xml->add( iv_name = 'DESCRIPTIONS'
ig_data = lt_descriptions ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
TYPES: BEGIN OF ty_includes,
programm TYPE programm,
END OF ty_includes.
TYPES: BEGIN OF ty_reposrc,
unam TYPE reposrc-unam,
udat TYPE reposrc-udat,
utime TYPE reposrc-utime,
END OF ty_reposrc.
DATA: lt_reposrc TYPE STANDARD TABLE OF ty_reposrc,
ls_reposrc LIKE LINE OF lt_reposrc,
lt_includes TYPE STANDARD TABLE OF ty_includes.
lt_includes = mi_object_oriented_object_fct->get_includes( ms_item-obj_name ).
ASSERT lines( lt_includes ) > 0.
SELECT unam udat utime FROM reposrc
INTO TABLE lt_reposrc
FOR ALL ENTRIES IN lt_includes
WHERE progname = lt_includes-programm
AND r3state = 'A'.
IF sy-subrc <> 0.
rv_user = c_user_unknown.
ELSE.
SORT lt_reposrc BY udat DESCENDING utime DESCENDING.
READ TABLE lt_reposrc INDEX 1 INTO ls_reposrc.
ASSERT sy-subrc = 0.
rv_user = ls_reposrc-unam.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: ls_clskey TYPE seoclskey.
ls_clskey-clsname = ms_item-obj_name.
mi_object_oriented_object_fct->delete( ls_clskey ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
deserialize_abap( io_xml = io_xml
iv_package = iv_package ).
deserialize_tpool( io_xml ).
deserialize_sotr( io_xml = io_xml
iv_package = iv_package ).
deserialize_docu( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: ls_class_key TYPE seoclskey.
ls_class_key-clsname = ms_item-obj_name.
rv_bool = mi_object_oriented_object_fct->exists( ls_class_key ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
DATA: lt_includes TYPE seoincl_t.
FIELD-SYMBOLS <lv_incl> LIKE LINE OF lt_includes.
lt_includes = mi_object_oriented_object_fct->get_includes( ms_item-obj_name ).
LOOP AT lt_includes ASSIGNING <lv_incl>.
rv_changed = check_prog_changed_since(
iv_program = <lv_incl>
iv_timestamp = iv_timestamp
iv_skip_gui = abap_true ).
IF rv_changed = abap_true.
RETURN.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'CLAS'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lt_source TYPE seop_source_string,
ls_class_key TYPE seoclskey.
ls_class_key-clsname = ms_item-obj_name.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
CALL FUNCTION 'SEO_BUFFER_REFRESH'
EXPORTING
version = seoc_version_active
force = seox_true.
CALL FUNCTION 'SEO_BUFFER_REFRESH'
EXPORTING
version = seoc_version_inactive
force = seox_true.
lt_source = mi_object_oriented_object_fct->serialize_abap( ls_class_key ).
mo_files->add_abap( lt_source ).
lt_source = mi_object_oriented_object_fct->serialize_abap(
is_class_key = ls_class_key
iv_type = seop_ext_class_locals_def ).
IF lines( lt_source ) > 0.
mo_files->add_abap( iv_extra = 'locals_def'
it_abap = lt_source ). "#EC NOTEXT
ENDIF.
lt_source = mi_object_oriented_object_fct->serialize_abap(
is_class_key = ls_class_key
iv_type = seop_ext_class_locals_imp ).
IF lines( lt_source ) > 0.
mo_files->add_abap( iv_extra = 'locals_imp'
it_abap = lt_source ). "#EC NOTEXT
ENDIF.
lt_source = mi_object_oriented_object_fct->serialize_abap(
is_class_key = ls_class_key
iv_type = seop_ext_class_testclasses ).
mv_skip_testclass = mi_object_oriented_object_fct->get_skip_test_classes( ).
IF lines( lt_source ) > 0 AND mv_skip_testclass = abap_false.
mo_files->add_abap( iv_extra = 'testclasses'
it_abap = lt_source ). "#EC NOTEXT
ENDIF.
lt_source = mi_object_oriented_object_fct->serialize_abap(
is_class_key = ls_class_key
iv_type = seop_ext_class_macros ).
IF lines( lt_source ) > 0.
mo_files->add_abap( iv_extra = 'macros'
it_abap = lt_source ). "#EC NOTEXT
ENDIF.
serialize_xml( io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
DATA: lv_classpool TYPE program.
lv_classpool = cl_oo_classname_service=>get_classpool_name( |{ ms_item-obj_name }| ).
IF is_class_locked( ) = abap_true
OR is_text_locked( lv_classpool ) = abap_true.
rv_is_locked = abap_true.
ENDIF.
ENDMETHOD.
METHOD is_class_locked.
DATA: lv_clsname TYPE seoclsenq-clsname.
lv_clsname = ms_item-obj_name.
OVERLAY lv_clsname WITH '=============================='.
CALL FUNCTION 'ENQUEUE_ESEOCLASS'
EXPORTING
clsname = lv_clsname
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
rv_is_class_locked = boolc( sy-subrc <> 0 ).
CALL FUNCTION 'DEQUEUE_ESEOCLASS'
EXPORTING
clsname = lv_clsname.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_clas_new IMPLEMENTATION.
METHOD get_metadata.
rs_metadata = super->get_metadata( ).
rs_metadata-class = 'ZCL_ABAPGIT_OBJECT_CLAS'.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_clas IMPLEMENTATION.
METHOD constructor.
super->constructor( is_item = is_item
iv_language = iv_language ).
CREATE OBJECT mi_object_oriented_object_fct TYPE zcl_abapgit_oo_class_new.
ENDMETHOD.
METHOD deserialize_abap.
DATA: ls_vseoclass TYPE vseoclass,
lt_source TYPE seop_source_string,
lt_local_definitions TYPE seop_source_string,
lt_local_implementations TYPE seop_source_string,
lt_local_macros TYPE seop_source_string,
lt_test_classes TYPE seop_source_string,
lt_descriptions TYPE zif_abapgit_definitions=>ty_seocompotx_tt,
ls_class_key TYPE seoclskey.
lt_source = mo_files->read_abap( ).
lt_local_definitions = mo_files->read_abap( iv_extra = 'locals_def'
iv_error = abap_false ). "#EC NOTEXT
lt_local_implementations = mo_files->read_abap( iv_extra = 'locals_imp'
iv_error = abap_false ). "#EC NOTEXT
lt_local_macros = mo_files->read_abap( iv_extra = 'macros'
iv_error = abap_false ). "#EC NOTEXT
lt_test_classes = mo_files->read_abap( iv_extra = 'testclasses'
iv_error = abap_false ). "#EC NOTEXT
ls_class_key-clsname = ms_item-obj_name.
io_xml->read( EXPORTING iv_name = 'VSEOCLASS'
CHANGING cg_data = ls_vseoclass ).
mi_object_oriented_object_fct->create(
EXPORTING
iv_package = iv_package
CHANGING
cg_properties = ls_vseoclass ).
mi_object_oriented_object_fct->generate_locals(
is_key = ls_class_key
iv_force = seox_true
it_local_definitions = lt_local_definitions
it_local_implementations = lt_local_implementations
it_local_macros = lt_local_macros
it_local_test_classes = lt_test_classes ).
mi_object_oriented_object_fct->deserialize_source(
is_key = ls_class_key
it_source = lt_source ).
io_xml->read( EXPORTING iv_name = 'DESCRIPTIONS'
CHANGING cg_data = lt_descriptions ).
mi_object_oriented_object_fct->update_descriptions(
is_key = ls_class_key
it_descriptions = lt_descriptions ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_CHAR IMPLEMENTATION.
METHOD instantiate_char.
DATA: lv_new TYPE abap_bool,
lv_name TYPE cls_attribute_name.
SELECT SINGLE name FROM cls_attribute INTO lv_name WHERE name = ms_item-obj_name.
lv_new = boolc( sy-subrc <> 0 ).
lv_name = ms_item-obj_name.
TRY.
CREATE OBJECT ro_char
EXPORTING
im_name = lv_name
im_type_group = iv_type_group
im_new = lv_new.
CATCH cx_pak_invalid_data
cx_pak_not_authorized
cx_pak_invalid_state
cx_pak_wb_object_locked.
zcx_abapgit_exception=>raise( 'Error while instantiating CL_CLS_ATTRIBUTE' ).
ENDTRY.
IF lv_new = abap_false.
TRY.
ro_char->if_pak_wb_object~lock_and_refresh( ).
CATCH cx_pak_invalid_data
cx_pak_not_authorized
cx_pak_invalid_state
cx_pak_wb_object_locked.
zcx_abapgit_exception=>raise( |Could not aquire lock, CHAR { lv_name }| ).
ENDTRY.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
SELECT SINGLE changed_by FROM cls_attribute INTO rv_user
WHERE name = ms_item-obj_name
AND activation_state = 'A'.
IF rv_user IS INITIAL.
SELECT SINGLE created_by FROM cls_attribute INTO rv_user
WHERE name = ms_item-obj_name
AND activation_state = 'A'.
ENDIF.
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_char TYPE REF TO cl_cls_attribute,
lv_type_group TYPE cls_attribute-type_group,
lx_pak_error TYPE REF TO cx_root,
lv_text TYPE string.
SELECT SINGLE type_group FROM cls_attribute INTO lv_type_group
WHERE name = ms_item-obj_name
AND activation_state = 'A'.
lo_char = instantiate_char( lv_type_group ).
TRY.
lo_char->if_pak_wb_object~delete( ).
lo_char->if_pak_wb_object~save( ).
lo_char->if_pak_wb_object_internal~unlock( ).
CATCH cx_pak_invalid_state cx_pak_invalid_data cx_pak_not_authorized INTO lx_pak_error.
lv_text = lx_pak_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_char TYPE ty_char,
ls_description LIKE LINE OF ls_char-cls_attributet,
lo_char TYPE REF TO cl_cls_attribute,
lx_pak_error TYPE REF TO cx_root,
lv_text TYPE string.
FIELD-SYMBOLS: <ls_value> LIKE LINE OF ls_char-cls_attr_value,
<ls_valuet> LIKE LINE OF ls_char-cls_attr_valuet.
io_xml->read( EXPORTING iv_name = 'CHAR'
CHANGING cg_data = ls_char ).
tadir_insert( iv_package ).
lo_char = instantiate_char( ls_char-cls_attribute-type_group ).
TRY.
lo_char->if_cls_attribute~set_kind( ls_char-cls_attribute-kind ).
lo_char->if_cls_attribute~set_single_valued( ls_char-cls_attribute-is_single_valued ).
lo_char->if_cls_attribute~set_aspect(
im_aspect_for = ls_char-cls_attribute-is_aspect_for
im_aspect_value = ls_char-cls_attribute-aspect_value ).
lo_char->if_cls_attribute~set_default_flag( ls_char-cls_attribute-default_flag ).
lo_char->if_cls_attribute~set_default_value( ls_char-cls_attribute-default_value ).
lo_char->if_cls_attribute~set_sub_object_treatment( ls_char-cls_attribute-sub_obj_treatm ).
lo_char->if_cls_attribute~set_automatic_changes_allowed( ls_char-cls_attribute-automatic_change ).
lo_char->if_cls_attribute~set_manual_changes_allowed( ls_char-cls_attribute-manu_chag_allow ).
lo_char->if_cls_attribute~set_implicit_changes_allowed( ls_char-cls_attribute-implicit_change ).
lo_char->if_cls_attribute~set_expl_values_dominate_links( ls_char-cls_attribute-weak_links ).
lo_char->if_cls_attribute~set_assignment_package_rule( ls_char-cls_attribute-assignment_devc ).
lo_char->if_cls_attribute~set_hide_remark( ls_char-cls_attribute-hide_remark ).
lo_char->if_cls_attribute~set_visible_in_customer_system( ls_char-cls_attribute-visible_for_cust ).
lo_char->if_cls_attribute~set_value_table( ls_char-cls_attribute-value_table ).
lo_char->if_cls_attribute~set_vtable_field( ls_char-cls_attribute-vtable_field ).
lo_char->if_cls_attribute~set_vtable_icon_f( ls_char-cls_attribute-vtable_icon_f ).
lo_char->if_cls_attribute~set_vtext_langu_f( ls_char-cls_attribute-vtext_langu_f ).
lo_char->if_cls_attribute~set_vtext_table( ls_char-cls_attribute-vtext_table ).
lo_char->if_cls_attribute~set_vtext_text_f( ls_char-cls_attribute-vtext_text_f ).
lo_char->if_cls_attribute~set_vtext_value_f( ls_char-cls_attribute-vtext_value_f ).
lo_char->if_cls_attribute~set_existing_objects_only( ls_char-cls_attribute-existing_objects ).
lo_char->if_cls_attribute~set_objs_of_typegr( ls_char-cls_attribute-objs_of_typegr ).
lo_char->if_cls_attribute~set_obj_values_have_subtypes( ls_char-cls_attribute-objs_w_subtype ).
lo_char->if_cls_attribute~set_arbtry_val_type( ls_char-cls_attribute-arbtry_val_type ).
READ TABLE ls_char-cls_attributet INTO ls_description WITH KEY langu = sy-langu.
IF sy-subrc <> 0.
READ TABLE ls_char-cls_attributet INTO ls_description INDEX 1.
ENDIF.
lo_char->if_cls_attribute~set_description( ls_description-text ).
LOOP AT ls_char-cls_attr_value ASSIGNING <ls_value>.
<ls_value>-activation_state = 'I'.
ENDLOOP.
LOOP AT ls_char-cls_attr_valuet ASSIGNING <ls_valuet>.
<ls_valuet>-activation_state = 'I'.
ENDLOOP.
lo_char->if_cls_attribute~set_values(
im_values = ls_char-cls_attr_value
im_values_t = ls_char-cls_attr_valuet ).
set_default_package( iv_package ).
lo_char->if_pak_wb_object~save( ).
lo_char->if_pak_wb_object~activate( ).
lo_char->if_pak_wb_object_internal~unlock( ).
CATCH cx_pak_invalid_state cx_pak_invalid_data cx_pak_not_authorized INTO lx_pak_error.
lv_text = lx_pak_error->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~exists.
rv_bool = cl_cls_attribute=>exists_object_attribute( ms_item-obj_name ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for( iv_lock_object = 'ECLS_ATTRIBUTE'
iv_argument = |{ ms_item-obj_name }*| ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = ms_item-obj_type
EXCEPTIONS
not_executed = 1
invalid_object_type = 2
OTHERS = 3.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error from RS_TOOL_ACCESS, CHAR| ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_char TYPE ty_char.
CONSTANTS: lc_active TYPE c LENGTH 1 VALUE 'A'.
SELECT SINGLE * FROM cls_attribute INTO ls_char-cls_attribute
WHERE name = ms_item-obj_name
AND activation_state = lc_active.
CLEAR: ls_char-cls_attribute-created_by,
ls_char-cls_attribute-created_on,
ls_char-cls_attribute-changed_by,
ls_char-cls_attribute-changed_on.
SELECT * FROM cls_attributet INTO TABLE ls_char-cls_attributet
WHERE name = ms_item-obj_name
AND activation_state = lc_active.
SELECT * FROM cls_attr_value INTO TABLE ls_char-cls_attr_value
WHERE name = ms_item-obj_name
AND activation_state = lc_active.
SELECT * FROM cls_attr_valuet INTO TABLE ls_char-cls_attr_valuet
WHERE name = ms_item-obj_name
AND activation_state = lc_active.
io_xml->add( iv_name = 'CHAR'
ig_data = ls_char ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_AVAS IMPLEMENTATION.
METHOD insert_assignments.
DATA: lt_assignment TYPE STANDARD TABLE OF cls_assignment,
ls_assignment LIKE LINE OF lt_assignment,
ls_value LIKE LINE OF is_avas-values.
LOOP AT is_avas-values INTO ls_value.
CLEAR ls_assignment.
ls_assignment-guid = is_avas-header-guid.
ls_assignment-value = ls_value-value.
ls_assignment-trobjtype = is_avas-header-object-trobjtype.
ls_assignment-sobj_name = is_avas-header-object-sobj_name.
ls_assignment-object_type = is_avas-header-object-object_type.
ls_assignment-sub_key = is_avas-header-object-sub_key.
ls_assignment-attribute = is_avas-header-attribute.
ls_assignment-set_by = sy-uname.
ls_assignment-changed_on = sy-datum.
ls_assignment-remark = ls_value-remark.
APPEND ls_assignment TO lt_assignment.
ENDLOOP.
DELETE FROM cls_assignment WHERE guid = is_avas-header-guid.
INSERT cls_assignment FROM TABLE lt_assignment.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Error inserting into CLS_ASSIGNMENT| ).
ENDIF.
ENDMETHOD.
METHOD insert_links.
ENDMETHOD.
METHOD instantiate.
DATA: lv_id TYPE guid_32,
lo_err TYPE REF TO cx_root.
lv_id = ms_item-obj_name.
TRY.
CREATE OBJECT ro_avas
EXPORTING
im_assignment_id = lv_id.
CATCH cx_pak_wb_object_locked INTO lo_err.
zcx_abapgit_exception=>raise( |AVAS { lv_id }: locked: { lo_err->get_longtext( ) }| ).
CATCH cx_pak_not_authorized INTO lo_err.
zcx_abapgit_exception=>raise( |AVAS { lv_id }: not authorized: { lo_err->get_longtext( ) }| ).
CATCH cx_pak_invalid_state INTO lo_err.
zcx_abapgit_exception=>raise( |AVAS { lv_id }: invalid state: { lo_err->get_longtext( ) }| ).
CATCH cx_pak_invalid_data INTO lo_err.
zcx_abapgit_exception=>raise( |AVAS { lv_id }: invalid data: { lo_err->get_longtext( ) }| ).
ENDTRY.
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
DATA: lo_avas TYPE REF TO cl_cls_attr_value_assignment.
lo_avas = instantiate( ).
lo_avas->if_pak_wb_object~get_last_changed(
IMPORTING
ex_changed_by = rv_user ).
IF rv_user IS INITIAL.
rv_user = c_user_unknown.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_avas TYPE REF TO cl_cls_attr_value_assignment.
lo_avas = instantiate( ).
TRY.
lo_avas->if_cls_attr_value_assignment~lock_and_refresh(
im_allow_popups = abap_false ).
CATCH cx_pak_invalid_state
cx_pak_invalid_data
cx_pak_not_authorized
cx_pak_wb_object_locked.
zcx_abapgit_exception=>raise( |AVAS error| ).
ENDTRY.
lo_avas->if_pak_wb_object~delete( ).
lo_avas->if_pak_wb_object~save( ).
lo_avas->if_pak_wb_object_internal~unlock( ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_avas TYPE ty_avas.
io_xml->read( EXPORTING iv_name = 'AVAS'
CHANGING cg_data = ls_avas ).
ASSERT NOT ls_avas-header-guid IS INITIAL.
tadir_insert( iv_package ).
insert_assignments( ls_avas ).
insert_links( ls_avas ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_guid TYPE cls_assignment-guid.
SELECT SINGLE guid FROM cls_assignment INTO lv_guid
WHERE guid = ms_item-obj_name.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = exists_a_lock_entry_for(
iv_lock_object = 'CLS_ENQUEUE_STRU'
iv_argument = |{ ms_item-obj_name }| ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( |Todo, AVAS jump| ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_avas TYPE REF TO cl_cls_attr_value_assignment,
ls_avas TYPE ty_avas.
FIELD-SYMBOLS: <ls_value> LIKE LINE OF ls_avas-values,
<ls_link> LIKE LINE OF ls_avas-links.
lo_avas = instantiate( ).
ls_avas-header-guid = lo_avas->if_cls_attr_value_assignment~get_guid( ).
ls_avas-header-attribute = lo_avas->if_cls_attr_value_assignment~get_attribute( ).
ls_avas-header-object = lo_avas->if_cls_attr_value_assignment~get_object( ).
lo_avas->if_cls_attr_value_assignment~get_values(
IMPORTING
ex_values = ls_avas-values ).
lo_avas->if_cls_attr_value_assignment~get_links(
IMPORTING
ex_links = ls_avas-links ).
LOOP AT ls_avas-values ASSIGNING <ls_value>.
CLEAR: <ls_value>-set_by, <ls_value>-changed_on.
ENDLOOP.
LOOP AT ls_avas-links ASSIGNING <ls_link>.
CLEAR: <ls_link>-set_by, <ls_link>-changed_on.
ENDLOOP.
io_xml->add(
iv_name = 'AVAS'
ig_data = ls_avas ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_auth IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lv_fieldname TYPE authx-fieldname.
lv_fieldname = ms_item-obj_name.
CALL FUNCTION 'SUSR_AUTF_DELETE_FIELD'
EXPORTING
fieldname = lv_fieldname
EXCEPTIONS
delete_not_possible = 1
field_in_use = 2
not_existing = 3
no_authority = 4
OTHERS = 5.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from SUSR_AUTF_DELETE_FIELD' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: ls_authx TYPE authx,
lo_auth TYPE REF TO cl_auth_tools.
io_xml->read( EXPORTING iv_name = 'AUTHX'
CHANGING cg_data = ls_authx ).
CREATE OBJECT lo_auth.
IF lo_auth->add_afield_to_trkorr( ls_authx-fieldname ) <> 0.
zcx_abapgit_exception=>raise( 'Error deserializing AUTH' ).
ENDIF.
MODIFY authx FROM ls_authx.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error deserializing AUTH' ).
ENDIF.
CALL FUNCTION 'DB_COMMIT'.
lo_auth->set_authfld_info_from_db( ls_authx-fieldname ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_fieldname TYPE authx-fieldname.
SELECT SINGLE fieldname FROM authx
INTO lv_fieldname
WHERE fieldname = ms_item-obj_name. "#EC CI_GENBUFF
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
DATA: lv_field TYPE fieldname.
lv_field = ms_item-obj_name.
CALL FUNCTION 'SU20_MAINTAIN_SNGL'
EXPORTING
id_field = lv_field
id_wbo_mode = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: ls_authx TYPE authx.
SELECT SINGLE * FROM authx INTO ls_authx
WHERE fieldname = ms_item-obj_name. "#EC CI_GENBUFF
IF sy-subrc <> 0.
RETURN.
ENDIF.
io_xml->add( iv_name = 'AUTHX'
ig_data = ls_authx ).
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_OBJECT_ASFC IMPLEMENTATION.
METHOD zif_abapgit_object~changed_by.
rv_user = zcl_abapgit_objects_super=>c_user_unknown.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_generic TYPE REF TO zcl_abapgit_objects_generic.
CREATE OBJECT lo_generic
EXPORTING
is_item = ms_item.
lo_generic->delete( ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lo_generic TYPE REF TO zcl_abapgit_objects_generic.
CREATE OBJECT lo_generic
EXPORTING
is_item = ms_item.
lo_generic->deserialize(
iv_package = iv_package
io_xml = io_xml ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lo_generic TYPE REF TO zcl_abapgit_objects_generic.
CREATE OBJECT lo_generic
EXPORTING
is_item = ms_item.
rv_bool = lo_generic->exists( ).
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
rs_metadata-delete_tadir = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
METHOD zif_abapgit_object~jump.
zcx_abapgit_exception=>raise( |TODO: Jump| ).
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_generic TYPE REF TO zcl_abapgit_objects_generic.
CREATE OBJECT lo_generic
EXPORTING
is_item = ms_item.
lo_generic->serialize( io_xml ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_object_acid IMPLEMENTATION.
METHOD zif_abapgit_object~has_changed_since.
rv_changed = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~get_metadata.
rs_metadata = get_metadata( ).
ENDMETHOD.
METHOD zif_abapgit_object~changed_by.
rv_user = c_user_unknown.
ENDMETHOD.
METHOD create_object.
DATA: lv_name TYPE aab_id_name.
lv_name = ms_item-obj_name.
CREATE OBJECT ro_aab
EXPORTING
im_name = lv_name
EXCEPTIONS
name_not_allowed = 1
OTHERS = 2.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error creating CL_AAB_ID object' ).
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_object~serialize.
DATA: lo_aab TYPE REF TO cl_aab_id,
lv_description TYPE aab_id_descript.
IF zif_abapgit_object~exists( ) = abap_false.
RETURN.
ENDIF.
lo_aab = create_object( ).
lo_aab->get_descript(
IMPORTING ex_descript = lv_description
EXCEPTIONS no_description_found = 1 ).
io_xml->add( iv_name = 'DESCRIPTION'
ig_data = lv_description ).
ENDMETHOD.
METHOD zif_abapgit_object~deserialize.
DATA: lv_description TYPE aab_id_descript,
lo_aab TYPE REF TO cl_aab_id.
io_xml->read( EXPORTING iv_name = 'DESCRIPTION'
CHANGING cg_data = lv_description ).
lo_aab = create_object( ).
lo_aab->enqueue( ).
lo_aab->set_descript( lv_description ).
tadir_insert( iv_package ).
lo_aab->save( ).
ENDMETHOD.
METHOD zif_abapgit_object~delete.
DATA: lo_aab TYPE REF TO cl_aab_id.
lo_aab = create_object( ).
lo_aab->enqueue( ).
lo_aab->delete(
EXCEPTIONS
prop_error = 1
propt_error = 2
act_error = 3
cts_error = 4
cts_devclass = 5
id_not_found = 6
no_authorization = 7
id_still_used = 8
where_used_error = 9
OTHERS = 10 ).
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error deleting ACID object' ).
ENDIF.
lo_aab->dequeue( ).
ENDMETHOD.
METHOD zif_abapgit_object~exists.
DATA: lv_state TYPE flag,
lo_aab TYPE REF TO cl_aab_id.
lo_aab = create_object( ).
lo_aab->get_state(
IMPORTING
ex_state = lv_state ).
rv_bool = boolc( lv_state = abap_true ).
ENDMETHOD.
METHOD zif_abapgit_object~jump.
CALL FUNCTION 'RS_TOOL_ACCESS'
EXPORTING
operation = 'SHOW'
object_name = ms_item-obj_name
object_type = 'ACID'
in_new_window = abap_true.
ENDMETHOD.
METHOD zif_abapgit_object~compare_to_remote_version.
CREATE OBJECT ro_comparison_result TYPE zcl_abapgit_comparison_null.
ENDMETHOD.
METHOD zif_abapgit_object~is_locked.
rv_is_locked = abap_false.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_COMPARISON_NULL IMPLEMENTATION.
METHOD zif_abapgit_comparison_result~is_result_complete_halt.
rv_response = abap_false.
ENDMETHOD.
METHOD zif_abapgit_comparison_result~show_confirmation_dialog.
RETURN.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_val_obj_upl IMPLEMENTATION.
METHOD get_business_msgs_from_dom.
" downport from CL_APL_ECATT_VO_UPLOAD
DATA: li_section TYPE REF TO if_ixml_element,
lt_buss_msg_ref TYPE zif_abapgit_ecatt=>etvo_bus_msg_tabtype,
lv_exception_occurred TYPE etonoff,
lo_ecatt_vo TYPE REF TO object.
FIELD-SYMBOLS: <lg_ecatt_vo> TYPE any.
li_section = template_over_all->find_from_name_ns( 'ETVO_MSG' ).
IF NOT li_section IS INITIAL.
CALL FUNCTION 'SDIXML_DOM_TO_DATA'
EXPORTING
data_as_dom = li_section
IMPORTING
dataobject = lt_buss_msg_ref
EXCEPTIONS
illegal_object = 1
OTHERS = 2.
IF sy-subrc <> 0.
CLEAR lt_buss_msg_ref.
ENDIF.
ENDIF.
ASSIGN ('ECATT_OBJECT') TO <lg_ecatt_vo>.
ASSERT sy-subrc = 0.
lo_ecatt_vo = <lg_ecatt_vo>.
TRY.
CALL METHOD lo_ecatt_vo->('SET_BUSSINESS_MSG')
EXPORTING
im_buss_msg_ref = lt_buss_msg_ref.
CATCH cx_ecatt_apl INTO exception_to_raise.
lv_exception_occurred = 'X'.
ENDTRY.
IF lv_exception_occurred = 'X'.
raise_upload_exception( previous = exception_to_raise ).
ENDIF.
ENDMETHOD.
METHOD get_impl_detail_from_dom.
" downport from CL_APL_ECATT_VO_UPLOAD
DATA: li_section TYPE REF TO if_ixml_element,
ls_impl_details TYPE zif_abapgit_ecatt=>etvoimpl_det,
lv_exception_occurred TYPE etonoff,
lo_ecatt_vo TYPE REF TO object.
FIELD-SYMBOLS: <lg_ecatt_vo> TYPE any.
li_section = template_over_all->find_from_name_ns( 'IMPL_DET' ).
IF NOT li_section IS INITIAL.
CALL FUNCTION 'SDIXML_DOM_TO_DATA'
EXPORTING
data_as_dom = li_section
IMPORTING
dataobject = ls_impl_details
EXCEPTIONS
illegal_object = 1
OTHERS = 2.
IF sy-subrc <> 0.
CLEAR ls_impl_details.
ENDIF.
ENDIF.
ASSIGN ('ECATT_OBJECT') TO <lg_ecatt_vo>.
ASSERT sy-subrc = 0.
lo_ecatt_vo = <lg_ecatt_vo>.
TRY.
CALL METHOD lo_ecatt_vo->('SET_IMPL_DETAILS')
EXPORTING
im_impl_details = ls_impl_details.
CATCH cx_ecatt_apl INTO exception_to_raise.
lv_exception_occurred = 'X'.
ENDTRY.
IF lv_exception_occurred = 'X'.
raise_upload_exception( previous = exception_to_raise ).
ENDIF.
ENDMETHOD.
METHOD get_vo_flags_from_dom.
" downport from CL_APL_ECATT_VO_UPLOAD
DATA: li_section TYPE REF TO if_ixml_element,
lv_error_prio TYPE zif_abapgit_ecatt=>etvo_error_prio,
lv_invert_validation TYPE zif_abapgit_ecatt=>etvo_invert_validation,
lv_exception_occurred TYPE etonoff,
lo_ecatt_vo TYPE REF TO object.
FIELD-SYMBOLS: <lg_ecatt_vo> TYPE any.
li_section = template_over_all->find_from_name_ns( 'INVERT_VALIDATION' ).
IF NOT li_section IS INITIAL.
CALL FUNCTION 'SDIXML_DOM_TO_DATA'
EXPORTING
data_as_dom = li_section
IMPORTING
dataobject = lv_invert_validation
EXCEPTIONS
illegal_object = 1
OTHERS = 2.
IF sy-subrc <> 0.
CLEAR lv_invert_validation.
ENDIF.
ENDIF.
ASSIGN ('ECATT_OBJECT') TO <lg_ecatt_vo>.
ASSERT sy-subrc = 0.
lo_ecatt_vo = <lg_ecatt_vo>.
TRY.
CALL METHOD lo_ecatt_vo->('SET_INVERT_VALIDATION_FLAG')
EXPORTING
im_invert_validation = lv_invert_validation.
CATCH cx_ecatt_apl INTO exception_to_raise.
lv_exception_occurred = 'X'.
ENDTRY.
li_section = template_over_all->find_from_name_ns( 'ERROR_PRIORITY' ).
IF NOT li_section IS INITIAL.
CALL FUNCTION 'SDIXML_DOM_TO_DATA'
EXPORTING
data_as_dom = li_section
IMPORTING
dataobject = lv_error_prio
EXCEPTIONS
illegal_object = 1
OTHERS = 2.
IF sy-subrc <> 0.
CLEAR lv_invert_validation.
ENDIF.
ENDIF.
TRY.
CALL METHOD lo_ecatt_vo->('SET_ERROR_PRIORITY')
EXPORTING
im_error_prio = lv_error_prio.
CATCH cx_ecatt_apl INTO exception_to_raise.
lv_exception_occurred = 'X'.
ENDTRY.
IF lv_exception_occurred = 'X'.
raise_upload_exception( previous = exception_to_raise ).
ENDIF.
ENDMETHOD.
METHOD upload.
" We inherit from CL_APL_ECATT_UPLOAD because CL_APL_ECATT_VO_UPLOAD
" doesn't exist in 702
" downport from CL_APL_ECATT_VO_UPLOAD
DATA: lx_ex TYPE REF TO cx_ecatt_apl,
lv_exists TYPE etonoff,
lv_exc_occ TYPE etonoff,
ls_tadir TYPE tadir,
lo_ecatt_vo TYPE REF TO object,
lo_params TYPE REF TO cl_apl_ecatt_params.
FIELD-SYMBOLS: <lg_ecatt_vo> TYPE any,
<lg_params> TYPE data,
<lv_d_akh> TYPE data,
<lv_i_akh> TYPE data.
TRY.
ch_object-i_devclass = ch_object-d_devclass.
ASSIGN COMPONENT 'D_AKH' OF STRUCTURE ch_object
TO <lv_d_akh>. " doesn't exist in 702
ASSIGN COMPONENT 'I_AKH' OF STRUCTURE ch_object
TO <lv_i_akh>. " doesn't exist in 702
IF <lv_d_akh> IS ASSIGNED
AND <lv_i_akh> IS ASSIGNED.
<lv_i_akh> = <lv_d_akh>.
ENDIF.
super->upload(
CHANGING
ch_object = ch_object ).
upload_data_from_stream( ch_object-filename ).
CATCH cx_ecatt_apl INTO lx_ex.
IF template_over_all IS INITIAL.
RAISE EXCEPTION lx_ex.
ELSE.
lv_exc_occ = 'X'.
ENDIF.
ENDTRY.
TRY.
CALL METHOD ('GET_ATTRIBUTES_FROM_DOM_NEW') " doesn't exit in 702
CHANGING
ch_object = ch_object.
CATCH cx_ecatt_apl INTO lx_ex.
lv_exc_occ = 'X'.
ENDTRY.
ASSIGN ('ECATT_OBJECT') TO <lg_ecatt_vo>.
ASSERT sy-subrc = 0.
lo_ecatt_vo = <lg_ecatt_vo>.
ASSIGN lo_ecatt_vo->('PARAMS') TO <lg_params>.
ASSERT sy-subrc = 0.
lo_params = <lg_params>.
TRY.
get_impl_detail_from_dom( ).
CATCH cx_ecatt_apl INTO lx_ex.
lv_exc_occ = 'X'.
ENDTRY.
TRY.
get_vo_flags_from_dom( ).
CATCH cx_ecatt_apl INTO lx_ex.
lv_exc_occ = 'X'.
ENDTRY.
TRY.
get_business_msgs_from_dom( ).
CATCH cx_ecatt_apl INTO lx_ex.
lv_exc_occ = 'X'.
ENDTRY.
TRY.
CALL METHOD ('GET_PARAMS_FROM_DOM_NEW') " doesn't exist in 702
EXPORTING
im_params = lo_params.
CATCH cx_ecatt_apl INTO lx_ex.
lv_exc_occ = 'X'.
ENDTRY.
TRY.
get_variants_from_dom( lo_params ).
CATCH cx_ecatt_apl INTO lx_ex.
lv_exc_occ = 'X'.
ENDTRY.
TRY.
lv_exists = cl_apl_ecatt_object=>existence_check_object(
im_name = ch_object-d_obj_name
im_version = ch_object-d_obj_ver
im_obj_type = ch_object-s_obj_type
im_exists_any_version = 'X' ).
IF lv_exists EQ space.
CALL METHOD lo_ecatt_vo->('SET_TADIR_FOR_NEW_OBJECT')
EXPORTING
im_tadir_for_new_object = tadir_preset.
ENDIF.
CATCH cx_ecatt.
CLEAR lv_exists.
ENDTRY.
TRY.
CALL METHOD lo_ecatt_vo->('SAVE')
EXPORTING
im_do_commit = 'X'.
CATCH cx_ecatt_apl INTO lx_ex.
lv_exc_occ = 'X'.
ENDTRY.
TRY.
cl_apl_ecatt_object=>get_tadir_entry(
EXPORTING im_obj_name = ch_object-d_obj_name
im_obj_type = ch_object-s_obj_type
IMPORTING ex_tadir = ls_tadir ).
ch_object-d_devclass = ls_tadir-devclass.
CATCH cx_ecatt.
CLEAR ls_tadir.
ENDTRY.
IF lv_exc_occ = 'X'.
raise_upload_exception( previous = lx_ex ).
ENDIF.
ENDMETHOD.
METHOD upload_data_from_stream.
" Downport
template_over_all = zcl_abapgit_ecatt_helper=>upload_data_from_stream( mv_external_xml ).
ENDMETHOD.
METHOD z_set_stream_for_upload.
" downport from CL_ABAPGIT_ECATT_DATA_UPLOAD SET_STREAM_FOR_UPLOAD
mv_external_xml = iv_xml.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_val_obj_down IMPLEMENTATION.
METHOD download.
" We inherit from CL_APL_ECATT_DOWNLOAD because CL_APL_ECATT_VO_DOWNLOAD
" doesn't exist in 702
" Downport
DATA: lv_partyp TYPE string,
lo_ecatt_vo TYPE REF TO object.
FIELD-SYMBOLS: <lg_ecatt_vo> TYPE any,
<lt_params> TYPE REF TO cl_apl_ecatt_params.
load_help = im_load_help.
typ = im_object_type.
TRY.
cl_apl_ecatt_object=>show_object(
EXPORTING
im_obj_type = im_object_type
im_name = im_object_name
im_version = im_object_version
IMPORTING
re_object = ecatt_object ).
CATCH cx_ecatt INTO ex_ecatt.
RETURN.
ENDTRY.
lv_partyp = cl_apl_ecatt_const=>params_type_par.
ASSIGN ('ECATT_OBJECT') TO <lg_ecatt_vo>.
ASSERT sy-subrc = 0.
lo_ecatt_vo = <lg_ecatt_vo>.
set_attributes_to_template( ).
set_ecatt_impl_detail( ).
set_ecatt_flags( ).
set_business_msgs( ).
ASSIGN lo_ecatt_vo->('PARAMS')
TO <lt_params>.
ASSERT sy-subrc = 0.
get_general_params_data( im_params = <lt_params>
im_ptyp = lv_partyp ).
LOOP AT parm INTO wa_parm.
set_general_params_data_to_dom( ).
IF NOT wa_parm-val_type IS INITIAL.
set_deep_stru_to_dom( <lt_params> ).
set_deep_data_to_dom( im_params = <lt_params>
im_pindex = wa_parm-pindex ).
ENDIF.
ENDLOOP.
set_variants_to_dom( <lt_params> ).
download_data( ).
ENDMETHOD.
METHOD download_data.
" Downport
zcl_abapgit_ecatt_helper=>download_data(
EXPORTING
ii_template_over_all = template_over_all
IMPORTING
ev_xml_stream = mv_xml_stream
ev_xml_stream_size = mv_xml_stream_size ).
ENDMETHOD.
METHOD get_xml_stream.
rv_xml_stream = mv_xml_stream.
ENDMETHOD.
METHOD get_xml_stream_size.
rv_xml_stream_size = mv_xml_stream_size.
ENDMETHOD.
METHOD set_business_msgs.
DATA:
lt_buss_msg_ref TYPE zif_abapgit_ecatt=>etvo_bus_msg_tabtype,
li_element TYPE REF TO if_ixml_element,
li_insert_objects TYPE REF TO if_ixml_element,
lo_ecatt_vo TYPE REF TO object.
FIELD-SYMBOLS: <lg_ecatt_vo> TYPE any.
ASSIGN ('ECATT_OBJECT') TO <lg_ecatt_vo>.
ASSERT sy-subrc = 0.
lo_ecatt_vo = <lg_ecatt_vo>.
li_objects_node = template_over_all->create_simple_element(
name = 'BUSINESS_MESSAGES'
parent = root_node ).
CALL METHOD lo_ecatt_vo->('GET_BUSSINESS_MSG')
IMPORTING
ex_buss_msg_ref = lt_buss_msg_ref.
CALL FUNCTION 'SDIXML_DATA_TO_DOM'
EXPORTING
name = 'ETVO_MSG'
dataobject = lt_buss_msg_ref
IMPORTING
data_as_dom = li_element
CHANGING
document = template_over_all
EXCEPTIONS
illegal_name = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
li_insert_objects ?= template_over_all->find_from_name( 'BUSINESS_MESSAGES' ).
li_insert_objects->append_child( new_child = li_element ).
ENDMETHOD.
METHOD set_ecatt_flags.
DATA:
lv_invert_validation TYPE zif_abapgit_ecatt=>etvo_invert_validation,
lv_error_prio TYPE zif_abapgit_ecatt=>etvo_error_prio,
li_element TYPE REF TO if_ixml_element,
li_insert_objects TYPE REF TO if_ixml_element,
lo_ecatt_vo TYPE REF TO object.
FIELD-SYMBOLS: <lg_ecatt_vo> TYPE any.
li_objects_node = template_over_all->create_simple_element(
name = 'VO_FLAGS'
parent = root_node ).
ASSIGN ('ECATT_OBJECT') TO <lg_ecatt_vo>.
ASSERT sy-subrc = 0.
lo_ecatt_vo = <lg_ecatt_vo>.
CALL METHOD lo_ecatt_vo->('GET_INVERT_VALIDATION_FLAG')
RECEIVING
re_invert_validation = lv_invert_validation.
CALL FUNCTION 'SDIXML_DATA_TO_DOM'
EXPORTING
name = 'INVERT_VALIDATION'
dataobject = lv_invert_validation
IMPORTING
data_as_dom = li_element
CHANGING
document = template_over_all
EXCEPTIONS
illegal_name = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
li_insert_objects ?= template_over_all->find_from_name( 'VO_FLAGS' ).
li_insert_objects->append_child( new_child = li_element ).
CALL METHOD lo_ecatt_vo->('GET_ERROR_PRIORITY')
RECEIVING
re_error_prio = lv_error_prio.
CALL FUNCTION 'SDIXML_DATA_TO_DOM'
EXPORTING
name = 'ERROR_PRIORITY'
dataobject = lv_error_prio
IMPORTING
data_as_dom = li_element
CHANGING
document = template_over_all
EXCEPTIONS
illegal_name = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
li_insert_objects = template_over_all->find_from_name( 'VO_FLAGS' ).
li_insert_objects->append_child( new_child = li_element ).
ENDMETHOD.
METHOD set_ecatt_impl_detail.
DATA:
ls_impl_details TYPE zif_abapgit_ecatt=>etvoimpl_det,
li_element TYPE REF TO if_ixml_element,
li_insert_objects TYPE REF TO if_ixml_element,
lo_ecatt_vo TYPE REF TO object.
FIELD-SYMBOLS: <lg_ecatt_vo> TYPE any.
li_objects_node = template_over_all->create_simple_element(
name = 'IMPL_DETAILS'
parent = root_node ).
ASSIGN ('ECATT_OBJECT') TO <lg_ecatt_vo>.
ASSERT sy-subrc = 0.
lo_ecatt_vo = <lg_ecatt_vo>.
CALL METHOD lo_ecatt_vo->('GET_IMPL_DETAILS')
RECEIVING
re_impl_details = ls_impl_details.
CALL FUNCTION 'SDIXML_DATA_TO_DOM'
EXPORTING
name = 'IMPL_DET'
dataobject = ls_impl_details
IMPORTING
data_as_dom = li_element
CHANGING
document = template_over_all
EXCEPTIONS
illegal_name = 1
OTHERS = 2.
IF sy-subrc <> 0.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
ENDIF.
li_insert_objects = template_over_all->find_from_name( 'IMPL_DETAILS' ).
li_insert_objects->append_child( new_child = li_element ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_system_upl IMPLEMENTATION.
METHOD upload_data_from_stream.
" Downport
template_over_all = zcl_abapgit_ecatt_helper=>upload_data_from_stream( mv_external_xml ).
ENDMETHOD.
METHOD z_set_stream_for_upload.
" downport from CL_APL_ECATT_SYSTEMS_UPLOAD SET_STREAM_FOR_UPLOAD
mv_external_xml = iv_xml.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_system_downl IMPLEMENTATION.
METHOD download.
" Downport
DATA: lv_partyp TYPE string.
load_help = im_load_help.
typ = im_object_type.
TRY.
cl_apl_ecatt_object=>show_object(
EXPORTING
im_obj_type = im_object_type
im_name = im_object_name
im_version = im_object_version
IMPORTING
re_object = ecatt_object ).
CATCH cx_ecatt INTO ex_ecatt.
RETURN.
ENDTRY.
lv_partyp = cl_apl_ecatt_const=>params_type_par.
set_attributes_to_template( ).
set_systems_data_to_template( ).
download_data( ).
ENDMETHOD.
METHOD download_data.
" Downport
zcl_abapgit_ecatt_helper=>download_data(
EXPORTING
ii_template_over_all = template_over_all
IMPORTING
ev_xml_stream = mv_xml_stream
ev_xml_stream_size = mv_xml_stream_size ).
ENDMETHOD.
METHOD get_xml_stream.
rv_xml_stream = mv_xml_stream.
ENDMETHOD.
METHOD get_xml_stream_size.
rv_xml_stream_size = mv_xml_stream_size.
ENDMETHOD.
METHOD set_systems_data_to_template.
DATA: lo_ecatt_systems TYPE REF TO cl_apl_ecatt_system_data,
lt_sys_data TYPE etsys_def_tabtype,
ls_sys_data TYPE etsys_def,
li_item TYPE REF TO if_ixml_element,
li_sysdata_node TYPE REF TO if_ixml_element.
lo_ecatt_systems ?= ecatt_object.
lt_sys_data = lo_ecatt_systems->get_system_data( ).
li_sysdata_node = template_over_all->create_simple_element(
name = 'SYSTEMS_DATA'
parent = root_node ).
etpar_node = template_over_all->create_simple_element(
name = 'ETSYS_DEF'
parent = li_sysdata_node ).
LOOP AT lt_sys_data INTO ls_sys_data.
CLEAR: ls_sys_data-sys_desc, ls_sys_data-instance.
CALL FUNCTION 'SDIXML_DATA_TO_DOM'
EXPORTING
name = 'item'
dataobject = ls_sys_data
IMPORTING
data_as_dom = li_item
CHANGING
document = template_over_all
EXCEPTIONS
illegal_name = 1
OTHERS = 2.
etpar_node->append_child( new_child = li_item ).
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_sp_upload IMPLEMENTATION.
METHOD get_ecatt_sp.
" downport
DATA: li_ixml TYPE REF TO if_ixml,
li_section TYPE REF TO if_ixml_element,
li_dom TYPE REF TO if_ixml_document,
li_root TYPE REF TO if_ixml_node,
lv_start_profile TYPE etxml_line_str,
lv_exception_occurred TYPE etonoff,
lo_ecatt_sp TYPE REF TO object.
FIELD-SYMBOLS: <ecatt_object> TYPE any.
TRY.
li_section = template_over_all->find_from_name_ns( 'START_PROFILE' ).
IF NOT li_section IS INITIAL.
CLASS cl_ixml DEFINITION LOAD.
li_ixml = cl_ixml=>create( ).
li_dom = li_ixml->create_document( ).
li_root ?= li_section->clone( ).
li_dom->append_child( new_child = li_root ).
CALL FUNCTION 'SDIXML_DOM_TO_XML'
EXPORTING
document = li_dom
IMPORTING
xml_as_string = lv_start_profile.
ASSIGN ('ECATT_OBJECT') TO <ecatt_object>.
ASSERT sy-subrc = 0.
lo_ecatt_sp = <ecatt_object>.
CALL METHOD lo_ecatt_sp->('SET_SP_ATTRIBUTES')
EXPORTING
i_sp_xml = lv_start_profile.
ENDIF.
CATCH cx_ecatt_apl.
lv_exception_occurred = 'X'.
ENDTRY.
IF lv_exception_occurred = 'X'.
raise_upload_exception( previous = exception_to_raise ).
ENDIF.
ENDMETHOD.
METHOD upload.
" We inherit from CL_APL_ECATT_UPLOAD because CL_APL_ECATT_SP_UPLOAD
" doesn't exist in 702
" Downport
"26.03.2013
DATA: lx_ecatt TYPE REF TO cx_ecatt_apl,
lv_exists TYPE etonoff,
lv_exc_occ TYPE etonoff,
ls_tadir TYPE tadir,
lv_exception_occurred TYPE etonoff,
lo_ecatt_sp TYPE REF TO object.
FIELD-SYMBOLS: <ecatt_sp> TYPE any,
<lv_d_akh> TYPE data,
<lv_i_akh> TYPE data.
TRY.
ch_object-i_devclass = ch_object-d_devclass.
ASSIGN COMPONENT 'D_AKH' OF STRUCTURE ch_object
TO <lv_d_akh>. " doesn't exist in 702
ASSIGN COMPONENT 'I_AKH' OF STRUCTURE ch_object
TO <lv_i_akh>. " doesn't exist in 702
IF <lv_d_akh> IS ASSIGNED
AND <lv_i_akh> IS ASSIGNED.
<lv_i_akh> = <lv_d_akh>.
ENDIF.
super->upload(
CHANGING
ch_object = ch_object ).
upload_data_from_stream( ch_object-filename ).
CATCH cx_ecatt_apl INTO lx_ecatt.
IF template_over_all IS INITIAL.
RAISE EXCEPTION lx_ecatt.
ELSE.
lv_exc_occ = 'X'.
ENDIF.
ENDTRY.
TRY.
CALL METHOD ('GET_ATTRIBUTES_FROM_DOM_NEW') " doesn't exist in 720
CHANGING
ch_object = ch_object.
CATCH cx_ecatt_apl INTO lx_ecatt.
lv_exc_occ = 'X'.
ENDTRY.
ASSIGN me->ecatt_object TO <ecatt_sp>.
ASSERT sy-subrc = 0.
lo_ecatt_sp = <ecatt_sp>.
TRY.
get_ecatt_sp( ).
CATCH cx_ecatt_apl INTO lx_ecatt.
lv_exc_occ = 'X'.
ENDTRY.
TRY.
lv_exists = cl_apl_ecatt_object=>existence_check_object(
im_name = ch_object-d_obj_name
im_version = ch_object-d_obj_ver
im_obj_type = ch_object-s_obj_type
im_exists_any_version = 'X' ).
IF lv_exists EQ space.
CALL METHOD lo_ecatt_sp->('SET_TADIR_FOR_NEW_OBJECT')
EXPORTING
im_tadir_for_new_object = tadir_preset.
ENDIF.
CATCH cx_ecatt.
CLEAR lv_exists.
ENDTRY.
TRY.
CALL METHOD lo_ecatt_sp->('SAVE')
EXPORTING
im_do_commit = 'X'.
CATCH cx_ecatt_apl INTO lx_ecatt.
lv_exc_occ = 'X'.
ENDTRY.
TRY.
ecatt_object->close_object( im_suppress_events ='X' ).
CATCH cx_ecatt_apl INTO lx_ecatt.
lv_exception_occurred = 'X'.
ENDTRY.
TRY.
cl_apl_ecatt_object=>get_tadir_entry(
EXPORTING im_obj_name = ch_object-d_obj_name
im_obj_type = ch_object-s_obj_type
IMPORTING ex_tadir = ls_tadir ).
ch_object-d_devclass = ls_tadir-devclass.
CATCH cx_ecatt.
CLEAR ls_tadir.
ENDTRY.
IF lv_exc_occ = 'X'.
raise_upload_exception( previous = lx_ecatt ).
ENDIF.
ENDMETHOD.
METHOD upload_data_from_stream.
" Downport
template_over_all = zcl_abapgit_ecatt_helper=>upload_data_from_stream( mv_external_xml ).
ENDMETHOD.
METHOD z_set_stream_for_upload.
" downport from CL_APL_ECATT_START_PROFIL SET_STREAM_FOR_UPLOAD
mv_external_xml = iv_xml.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_sp_download IMPLEMENTATION.
METHOD download.
" We inherit from CL_APL_ECATT_DOWNLOAD because CL_APL_ECATT_SP_DOWNLOAD
" doesn't exist in 702
" Downport
DATA: lv_partyp TYPE string.
load_help = im_load_help.
typ = im_object_type.
TRY.
cl_apl_ecatt_object=>show_object(
EXPORTING
im_obj_type = im_object_type
im_name = im_object_name
im_version = im_object_version
IMPORTING
re_object = ecatt_object ).
CATCH cx_ecatt INTO ex_ecatt.
RETURN.
ENDTRY.
lv_partyp = cl_apl_ecatt_const=>params_type_par.
set_attributes_to_template( ).
set_sp_data_to_template( ).
download_data( ).
ENDMETHOD.
METHOD download_data.
" Downport
zcl_abapgit_ecatt_helper=>download_data(
EXPORTING
ii_template_over_all = template_over_all
IMPORTING
ev_xml_stream = mv_xml_stream
ev_xml_stream_size = mv_xml_stream_size ).
ENDMETHOD.
METHOD get_xml_stream.
rv_xml_stream = mv_xml_stream.
ENDMETHOD.
METHOD get_xml_stream_size.
rv_xml_stream_size = mv_xml_stream_size.
ENDMETHOD.
METHOD set_sp_data_to_template.
" downport
DATA: li_dom TYPE REF TO if_ixml_document,
li_start_profile_data_node TYPE REF TO if_ixml_element,
li_element TYPE REF TO if_ixml_element,
lv_sp_xml TYPE etxml_line_str,
lo_ecatt_sp TYPE REF TO object.
FIELD-SYMBOLS: <ecatt_object> TYPE data.
li_start_profile_data_node = template_over_all->create_simple_element(
name = 'START_PROFILE'
parent = root_node ).
ASSIGN ('ECATT_OBJECT') TO <ecatt_object>.
ASSERT sy-subrc = 0.
lo_ecatt_sp = <ecatt_object>.
TRY.
CALL METHOD lo_ecatt_sp->('GET_SP_ATTRIBUTES')
IMPORTING
e_sp_xml = lv_sp_xml.
CATCH cx_ecatt_apl.
ENDTRY.
CALL FUNCTION 'SDIXML_XML_TO_DOM'
EXPORTING
xml = lv_sp_xml
IMPORTING
document = li_dom.
li_element = li_dom->get_root_element( ).
li_start_profile_data_node->append_child( new_child = li_element ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_ECATT_SCRIPT_UPL IMPLEMENTATION.
METHOD upload_data_from_stream.
" Downport
template_over_all = zcl_abapgit_ecatt_helper=>upload_data_from_stream( mv_external_xml ).
ENDMETHOD.
METHOD z_set_stream_for_upload.
" downport from CL_ABAPGIT_ECATT_DATA_UPLOAD SET_STREAM_FOR_UPLOAD
mv_external_xml = iv_xml.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_ECATT_SCRIPT_DOWNL IMPLEMENTATION.
METHOD download.
" Downport
DATA: lv_partyp TYPE string,
lx_ecatt TYPE REF TO cx_ecatt_apl.
load_help = im_load_help.
typ = im_object_type.
TRY.
cl_apl_ecatt_object=>show_object(
EXPORTING
im_obj_type = im_object_type
im_name = im_object_name
im_version = im_object_version
IMPORTING
re_object = ecatt_object ).
CATCH cx_ecatt INTO ex_ecatt.
RETURN.
ENDTRY.
toolname = ecatt_object->attrib->get_tool_name( ).
set_attributes_to_template( ).
IF toolname EQ cl_apl_ecatt_const=>toolname_ecatt.
ecatt_script ?= ecatt_object.
set_script_to_template( ).
TRY.
get_general_params_data( ecatt_script->params ).
CATCH cx_ecatt_apl INTO lx_ecatt. "#EC NOHANDLER
ENDTRY.
LOOP AT parm INTO wa_parm.
TRY.
IF wa_parm-value = '<INITIAL>'.
CLEAR wa_parm-value.
ENDIF.
set_general_params_data_to_dom( ).
IF NOT wa_parm-pstruc_typ IS INITIAL.
set_deep_stru_to_dom( ecatt_script->params ).
set_deep_data_to_dom( ecatt_script->params ).
IF wa_parm-xmlref_typ EQ cl_apl_ecatt_const=>ref_type_c_tcd.
set_control_data_for_tcd( is_param = wa_parm
io_params = ecatt_script->params ).
ENDIF.
ENDIF.
CATCH cx_ecatt_apl INTO lx_ecatt. "#EC NOHANDLER
ENDTRY.
ENDLOOP.
ELSE.
set_blob_to_template( ).
set_artmp_to_template( ).
ENDIF.
download_data( ).
ENDMETHOD.
METHOD download_data.
" Downport
zcl_abapgit_ecatt_helper=>download_data(
EXPORTING
ii_template_over_all = template_over_all
IMPORTING
ev_xml_stream = mv_xml_stream
ev_xml_stream_size = mv_xml_stream_size ).
ENDMETHOD.
METHOD escape_control_data.
" Downport
DATA: li_iter TYPE REF TO if_ixml_node_iterator,
li_textit TYPE REF TO if_ixml_node_iterator,
li_abapctrl TYPE REF TO if_ixml_node_collection,
li_text TYPE REF TO if_ixml_text,
li_filter TYPE REF TO if_ixml_node_filter,
li_list TYPE REF TO if_ixml_node_list,
lv_value TYPE etdom_name,
li_vars TYPE REF TO if_ixml_element,
li_elem TYPE REF TO if_ixml_element.
li_vars = ii_element->find_from_name_ns( iv_tabname ).
li_filter = ii_element->create_filter_node_type(
if_ixml_node=>co_node_text ).
IF li_vars IS NOT INITIAL.
li_abapctrl = ii_element->get_elements_by_tag_name_ns( iv_node ).
li_iter = li_abapctrl->create_iterator( ).
li_elem ?= li_iter->get_next( ).
WHILE li_elem IS NOT INITIAL.
li_list = li_elem->get_children( ).
li_textit = li_list->create_rev_iterator_filtered( li_filter ).
li_text ?= li_textit->get_next( ).
IF li_text IS NOT INITIAL.
lv_value = li_text->get_data( ).
IF lv_value(1) = cl_abap_char_utilities=>minchar.
REPLACE SECTION OFFSET 0 LENGTH 1 OF lv_value WITH space.
li_text->set_value( value = lv_value ).
ENDIF.
ENDIF.
CLEAR: li_textit, li_list, li_elem, lv_value.
li_elem ?= li_iter->get_next( ).
ENDWHILE.
CLEAR: li_abapctrl, li_elem, li_iter.
ENDIF.
ENDMETHOD.
METHOD get_xml_stream.
rv_xml_stream = mv_xml_stream.
ENDMETHOD.
METHOD get_xml_stream_size.
rv_xml_stream_size = mv_xml_stream_size.
ENDMETHOD.
METHOD set_artmp_to_template.
" Downport
DATA: li_artmp_node TYPE REF TO if_ixml_element,
lv_rc TYPE sy-subrc,
lv_text TYPE string,
lv_rc_args_tmpl TYPE int4,
lv_errmsg TYPE string.
li_artmp_node = template_over_all->create_simple_element(
name = 'ECET_ARTMP'
parent = root_node ).
ecatt_extprog->get_args_tmpl(
IMPORTING
ex_xml_arg_tmpl = lv_text
ex_rc = lv_rc_args_tmpl
ex_errmsg = lv_errmsg ).
IF li_artmp_node IS INITIAL OR lv_rc_args_tmpl > 0.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt
called_method = 'CL_APL_ECATT_SCRIPT_DOWNLOAD->SET_ARTMP_TO_TEMPLATE'
free_text = lv_errmsg ).
ENDIF.
lv_rc = li_artmp_node->set_value( value = lv_text ).
IF lv_rc <> 0.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt
called_method = 'CL_APL_ECATT_SCRIPT_DOWNLOAD->SET_ARTMP_TO_TEMPLATE' ).
ENDIF.
ENDMETHOD.
METHOD set_blob_to_template.
" Downport
DATA: li_blob_node TYPE REF TO if_ixml_element,
lv_rc TYPE sy-subrc,
lv_text TYPE string.
li_blob_node = template_over_all->create_simple_element(
name = 'ECET_BLOBS'
parent = root_node ).
IF li_blob_node IS INITIAL.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt
called_method = 'CL_APL_ECATT_SCRIPT_DOWNLOAD->SET_BLOB_TO_TEMPLATE' ).
ENDIF.
ecatt_extprog->get_blob(
EXPORTING
im_whole_data = 1
IMPORTING
ex_xml_blob = lv_text ).
lv_rc = li_blob_node->set_value( value = lv_text ).
IF lv_rc <> 0.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt
called_method = 'CL_APL_ECATT_SCRIPT_DOWNLOAD->SET_BLOB_TO_TEMPLATE' ).
ENDIF.
ENDMETHOD.
METHOD set_control_data_for_tcd.
" Downport
DATA: lt_params TYPE ettcd_params_tabtype,
lt_verbs TYPE ettcd_verbs_tabtype,
lt_vars TYPE ettcd_vars_tabtype,
lt_dp_tab TYPE ettcd_dp_tab_tabtype,
lt_dp_for TYPE ettcd_dp_for_tabtype,
lt_dp_pro TYPE ettcd_dp_pro_tabtype,
lt_dp_fld TYPE ettcd_dp_fld_tabtype,
lt_svars TYPE ettcd_svars_tabtype.
DATA: li_element TYPE REF TO if_ixml_element,
li_deep_tcd TYPE REF TO if_ixml_element,
lv_rc TYPE sy-subrc,
lv_name TYPE string,
lv_parname TYPE string,
lo_pval_xml TYPE REF TO cl_apl_ecatt_xml_data,
lo_ctrl_tabs TYPE REF TO cl_apl_ecatt_control_tables.
FIELD-SYMBOLS: <lt_tab> TYPE STANDARD TABLE.
IF is_param-xmlref_typ <> cl_apl_ecatt_const=>ref_type_c_tcd
OR io_params IS INITIAL.
RETURN.
ENDIF.
lv_parname = is_param-pname.
io_params->get_param_value( "TCD command interface
EXPORTING
im_var_id = cl_apl_ecatt_const=>varid_default_val
im_pname = lv_parname
im_pindex = is_param-pindex
IMPORTING
ex_pval_xml = lo_pval_xml ).
lo_ctrl_tabs = lo_pval_xml->get_control_tables_ref( ).
IF lo_ctrl_tabs IS INITIAL.
RETURN.
ENDIF.
lo_ctrl_tabs->get_control_tables( "Read 8 control tables
IMPORTING
ex_params = lt_params
ex_verbs = lt_verbs
ex_vars = lt_vars
ex_dp_tab = lt_dp_tab
ex_dp_for = lt_dp_for
ex_dp_pro = lt_dp_pro
ex_dp_fld = lt_dp_fld
ex_svars = lt_svars ).
IF lt_params IS INITIAL OR
lt_verbs IS INITIAL OR
lt_vars IS INITIAL OR
lt_dp_tab IS INITIAL OR
lt_dp_for IS INITIAL OR
lt_dp_pro IS INITIAL OR
lt_dp_fld IS INITIAL OR
lt_svars IS INITIAL.
RETURN.
ENDIF.
li_deep_tcd = template_over_all->create_simple_element_ns(
name = cl_apl_xml_const=>upl_tcd_node
parent = ap_current_param ).
IF li_deep_tcd IS INITIAL.
raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt ).
ENDIF.
DO 8 TIMES. "Loop at 8 control tables
CASE sy-index.
WHEN 1.
lv_name = 'ETTCD_PARAMS_TABTYPE'.
ASSIGN lt_params TO <lt_tab>.
WHEN 2.
lv_name = 'ETTCD_VERBS_TABTYPE'.
ASSIGN lt_verbs TO <lt_tab>.
WHEN 3.
lv_name = 'ETTCD_VARS_TABTYPE'.
ASSIGN lt_vars TO <lt_tab>.
WHEN 4.
lv_name = 'ETTCD_DP_TAB_TABTYPE'.
ASSIGN lt_dp_tab TO <lt_tab>.
WHEN 5.
lv_name = 'ETTCD_DP_FOR_TABTYPE'.
ASSIGN lt_dp_for TO <lt_tab>.
WHEN 6.
lv_name = 'ETTCD_DP_PRO_TABTYPE'.
ASSIGN lt_dp_pro TO <lt_tab>.
WHEN 7.
lv_name = 'ETTCD_DP_FLD_TABTYPE'.
ASSIGN lt_dp_fld TO <lt_tab>.
WHEN 8.
lv_name = 'ETTCD_SVARS_TABTYPE'.
ASSIGN lt_svars TO <lt_tab>.
ENDCASE.
CALL FUNCTION 'SDIXML_DATA_TO_DOM' "Ast generieren lassen
EXPORTING
name = lv_name
dataobject = <lt_tab>
IMPORTING
data_as_dom = li_element
EXCEPTIONS
illegal_name = 1
OTHERS = 2.
IF sy-subrc <> 0.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt ).
ENDIF.
lv_rc = li_deep_tcd->append_child( new_child = li_element ).
IF lv_rc <> 0.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt ).
ENDIF.
FREE li_element.
UNASSIGN <lt_tab>.
ENDDO.
escape_control_data( ii_element = li_deep_tcd
iv_tabname = 'ETTCD_VARS_TABTYPE'
iv_node = 'CB_INDEX' ).
escape_control_data(
ii_element = li_deep_tcd
iv_tabname = 'ETTCD_VERBS_TABTYPE'
iv_node = 'NAME' ).
FREE: lt_dp_tab, lt_dp_for, lt_dp_fld, lt_svars,
lt_params, lt_vars, lt_dp_pro, lt_verbs.
ENDMETHOD.
METHOD set_script_to_template.
" Downport
DATA:
lt_text TYPE etxml_line_tabtype,
li_element TYPE REF TO if_ixml_element,
lv_rc TYPE sy-subrc.
ecatt_script->get_script_text(
CHANGING
scripttext = lt_text ).
mi_script_node = template_over_all->create_simple_element(
name = 'SCRIPT'
parent = root_node ).
IF mi_script_node IS INITIAL.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt
called_method = 'CL_APL_ECATT_SCRIPT_DOWNLOAD->SET_SCRIPT_TO_TEMPLATE' ).
ENDIF.
CALL FUNCTION 'SDIXML_DATA_TO_DOM'
EXPORTING
name = 'ETXML_LINE_TABTYPE'
dataobject = lt_text
IMPORTING
data_as_dom = li_element
CHANGING
document = template_over_all
EXCEPTIONS
illegal_name = 1
OTHERS = 2.
IF sy-subrc <> 0.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt
called_method = 'CL_APL_ECATT_SCRIPT_DOWNLOAD->SET_SCRIPT_TO_TEMPLATE' ).
ENDIF.
lv_rc = mi_script_node->append_child( li_element ).
IF lv_rc <> 0.
me->raise_download_exception(
textid = cx_ecatt_apl_util=>download_processing
previous = ex_ecatt
called_method = 'CL_APL_ECATT_SCRIPT_DOWNLOAD->SET_SCRIPT_TO_TEMPLATE' ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_helper IMPLEMENTATION.
METHOD build_xml_of_object.
" downport of CL_APL_ECATT_DOWNLOAD=>BUILD_XML_OF_OBJECT
DATA: lo_load_help_dummy TYPE REF TO cl_apl_ecatt_load_help,
lx_ecatt TYPE REF TO cx_ecatt_apl,
lv_text TYPE string.
"download method will create the xml stream
"note: it's the redefined download( ) of each object type specific download, which is called
TRY.
CREATE OBJECT lo_load_help_dummy
EXPORTING
im_maintain_function = ''.
io_download->download( im_object_name = im_object_name
im_object_version = im_object_version
im_object_type = im_object_type
im_load_help = lo_load_help_dummy ).
CATCH cx_ecatt_apl INTO lx_ecatt.
lv_text = lx_ecatt->get_text( ).
zcx_abapgit_exception=>raise( lv_text ).
" CATCH cx_ecatt_ui_attachment. " Doesn't exist in 702
CATCH cx_ecatt.
"will never be raised from download, when called with mv_generate_xml_no_download = 'X'.
ENDTRY.
CALL METHOD io_download->('GET_XML_STREAM')
RECEIVING
rv_xml_stream = ex_xml_stream.
CALL METHOD io_download->('GET_XML_STREAM_SIZE')
RECEIVING
rv_xml_stream_size = ex_xml_stream_size.
ENDMETHOD.
METHOD download_data.
DATA:
lv_xtab TYPE etxml_xline_tabtype,
lo_xml TYPE REF TO cl_apl_ecatt_xml,
lv_size TYPE int4,
lx_ecatt TYPE REF TO cx_ecatt_apl_xml.
CLEAR: ev_xml_stream,
ev_xml_stream_size.
TRY.
CALL METHOD cl_apl_ecatt_xml=>('CREATE') " doesn't exist in 702
EXPORTING
im_type = co_xml
RECEIVING
re_xml = lo_xml.
lo_xml->set_attributes( im_dom = ii_template_over_all ).
lo_xml->get_attributes(
IMPORTING
ex_xtab = lv_xtab
ex_size_xstring = lv_size
ex_xml = ev_xml_stream ).
ev_xml_stream_size = lv_size.
CATCH cx_ecatt_apl_xml INTO lx_ecatt.
RETURN.
ENDTRY.
ENDMETHOD.
METHOD upload_data_from_stream.
DATA:
lt_eing TYPE etxml_xline_tabtype,
lo_xml TYPE REF TO cl_apl_ecatt_xml,
lv_xstr TYPE xstring,
lv_nc_xmlref_typ TYPE REF TO if_ixml_node_collection,
lv_n_xmlref_typ TYPE REF TO if_ixml_node,
lv_index TYPE i VALUE 0,
lv_count TYPE i.
lv_xstr = iv_xml_stream.
CALL METHOD cl_apl_ecatt_xml=>('CREATE') " doesn't exist in 702
EXPORTING
im_type = co_xml
RECEIVING
re_xml = lo_xml.
lo_xml->stream_to_dom( im_xstream = lv_xstr
im_ignore_white_space = 'X'
im_uri = cl_apl_xml_const=>schema_uri ).
lo_xml->get_attributes(
IMPORTING
ex_dom = ri_template_over_all ).
lv_nc_xmlref_typ ?= ri_template_over_all->get_elements_by_tag_name_ns(
'XMLREF_TYP' ). "#EC NOTEXT
CALL METHOD lv_nc_xmlref_typ->('GET_LENGTH') " downport
RECEIVING
rval = lv_count.
WHILE lv_index LT lv_count.
lv_n_xmlref_typ = lv_nc_xmlref_typ->get_item( lv_index ).
lv_n_xmlref_typ->set_name( 'X-MLREF_TYP' ).
lv_index = lv_index + 1.
ENDWHILE.
FREE: lt_eing.
CLEAR: lo_xml, lv_xstr.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_data_upload IMPLEMENTATION.
METHOD upload_data_from_stream.
" Downport
template_over_all = zcl_abapgit_ecatt_helper=>upload_data_from_stream( mv_external_xml ).
ENDMETHOD.
METHOD z_set_stream_for_upload.
" donwnpoort from CL_ABAPGIT_ECATT_DATA_UPLOAD SET_STREAM_FOR_UPLOAD
mv_external_xml = iv_xml.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_ECATT_DATA_DOWNL IMPLEMENTATION.
METHOD download.
" Downport
DATA: lv_partyp TYPE string.
load_help = im_load_help.
TRY.
cl_apl_ecatt_object=>show_object(
EXPORTING
im_obj_type = im_object_type
im_name = im_object_name
im_version = im_object_version
IMPORTING
re_object = ecatt_object ).
CATCH cx_ecatt INTO ex_ecatt.
RETURN.
ENDTRY.
typ = im_object_type.
lv_partyp = cl_apl_ecatt_const=>params_type_par.
ecatt_data ?= ecatt_object.
set_attributes_to_template( ).
get_general_params_data( im_params = ecatt_data->params
im_ptyp = lv_partyp ).
LOOP AT parm INTO wa_parm.
set_general_params_data_to_dom( ).
IF NOT wa_parm-val_type IS INITIAL.
set_deep_stru_to_dom( ecatt_data->params ).
set_deep_data_to_dom( im_params = ecatt_data->params
im_pindex = wa_parm-pindex ).
ENDIF.
ENDLOOP.
set_var_mode_to_dom( ).
set_variants_to_dom( ecatt_data->params ).
download_data( ).
ENDMETHOD.
METHOD download_data.
" Downport
zcl_abapgit_ecatt_helper=>download_data(
EXPORTING
ii_template_over_all = template_over_all
IMPORTING
ev_xml_stream = mv_xml_stream
ev_xml_stream_size = mv_xml_stream_size ).
ENDMETHOD.
METHOD get_xml_stream.
rv_xml_stream = mv_xml_stream.
ENDMETHOD.
METHOD get_xml_stream_size.
rv_xml_stream_size = mv_xml_stream_size.
ENDMETHOD.
METHOD set_generate_xml_no_download.
mv_generate_xml_no_download = iv_generate_xml_no_download.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_config_upl IMPLEMENTATION.
METHOD upload_data_from_stream.
" Downport
template_over_all = zcl_abapgit_ecatt_helper=>upload_data_from_stream( mv_external_xml ).
ENDMETHOD.
METHOD z_set_stream_for_upload.
" downport from CL_ABAPGIT_ECATT_DATA_UPLOAD SET_STREAM_FOR_UPLOAD
mv_external_xml = iv_xml.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_ecatt_config_downl IMPLEMENTATION.
METHOD download.
" Downport
DATA: lv_partyp TYPE string.
load_help = im_load_help.
typ = im_object_type.
TRY.
cl_apl_ecatt_object=>show_object(
EXPORTING
im_obj_type = im_object_type
im_name = im_object_name
im_version = im_object_version
IMPORTING
re_object = ecatt_object ).
CATCH cx_ecatt INTO ex_ecatt.
RETURN.
ENDTRY.
lv_partyp = cl_apl_ecatt_const=>params_type_par.
set_attributes_to_template( ).
ecatt_config ?= ecatt_object.
CALL METHOD ('SET_ECATT_OBJECTS_TO_TEMPLATE'). " doesn't exist in 702
set_var_mode_to_dom( ).
get_general_params_data( im_params = ecatt_config->params
im_ptyp = lv_partyp ).
LOOP AT parm INTO wa_parm.
set_general_params_data_to_dom( ).
IF NOT wa_parm-val_type IS INITIAL.
set_deep_stru_to_dom( ecatt_config->params ).
set_deep_data_to_dom( im_params = ecatt_config->params
im_pindex = wa_parm-pindex ).
ENDIF.
ENDLOOP.
set_variants_to_dom( ecatt_config->params ).
download_data( ).
ENDMETHOD.
METHOD download_data.
" Downport
zcl_abapgit_ecatt_helper=>download_data(
EXPORTING
ii_template_over_all = template_over_all
IMPORTING
ev_xml_stream = mv_xml_stream
ev_xml_stream_size = mv_xml_stream_size ).
ENDMETHOD.
METHOD get_xml_stream.
rv_xml_stream = mv_xml_stream.
ENDMETHOD.
METHOD get_xml_stream_size.
rv_xml_stream_size = mv_xml_stream_size.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PROXY_CONFIG IMPLEMENTATION.
METHOD constructor.
mo_settings = zcl_abapgit_persist_settings=>get_instance( )->read( ).
mi_exit = zcl_abapgit_exit=>get_instance( ).
ENDMETHOD.
METHOD get_proxy_authentication.
rv_auth = mo_settings->get_proxy_authentication( ).
mi_exit->change_proxy_authentication(
EXPORTING
iv_repo_url = iv_repo_url
CHANGING
cv_proxy_authentication = rv_auth ).
ENDMETHOD.
METHOD get_proxy_port.
rv_port = mo_settings->get_proxy_port( ).
mi_exit->change_proxy_port(
EXPORTING
iv_repo_url = iv_repo_url
CHANGING
cv_proxy_port = rv_port ).
ENDMETHOD.
METHOD get_proxy_url.
rv_proxy_url = mo_settings->get_proxy_url( ).
mi_exit->change_proxy_url(
EXPORTING
iv_repo_url = iv_repo_url
CHANGING
cv_proxy_url = rv_proxy_url ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_PROXY_AUTH IMPLEMENTATION.
METHOD enter.
zcl_abapgit_password_dialog=>popup(
EXPORTING
iv_repo_url = 'Proxy Authentication'
CHANGING
cv_user = gv_username
cv_pass = gv_password ).
IF gv_username IS INITIAL OR gv_password IS INITIAL.
zcx_abapgit_exception=>raise( 'Proxy auth failed' ).
ENDIF.
ENDMETHOD.
METHOD run.
IF gv_username IS INITIAL OR gv_password IS INITIAL.
enter( ).
ENDIF.
ii_client->authenticate(
proxy_authentication = abap_true
username = gv_username
password = gv_password ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_HTTP_DIGEST IMPLEMENTATION.
METHOD constructor.
parse( ii_client ).
mv_ha1 = md5( |{ iv_username }:{ mv_realm }:{ iv_password }| ).
mv_username = iv_username.
ENDMETHOD.
METHOD hash.
DATA: lv_ha2 TYPE string.
lv_ha2 = md5( |{ iv_method }:{ iv_uri }| ).
ASSERT NOT iv_cnonse IS INITIAL.
rv_response = md5( |{ mv_ha1 }:{ iv_nonce }:{ gv_nc }:{ iv_cnonse }:{ iv_qop }:{ lv_ha2 }| ).
ENDMETHOD.
METHOD md5.
DATA: lv_xstr TYPE xstring,
lv_hash TYPE xstring.
lv_xstr = zcl_abapgit_convert=>string_to_xstring_utf8( iv_data ).
CALL FUNCTION 'CALCULATE_HASH_FOR_RAW'
EXPORTING
alg = 'MD5'
data = lv_xstr
IMPORTING
hashxstring = lv_hash
EXCEPTIONS
unknown_alg = 1
param_error = 2
internal_error = 3
OTHERS = 4.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'error from CALCULATE_HASH_FOR_RAW' ).
ENDIF.
rv_hash = lv_hash.
TRANSLATE rv_hash TO LOWER CASE.
ENDMETHOD.
METHOD parse.
DATA: lv_value TYPE string.
lv_value = ii_client->response->get_header_field( 'www-authenticate' ).
FIND REGEX 'realm="([\w ]+)"' IN lv_value SUBMATCHES mv_realm.
FIND REGEX 'qop="(\w+)"' IN lv_value SUBMATCHES mv_qop.
FIND REGEX 'nonce="([\w=/+\$]+)"' IN lv_value SUBMATCHES mv_nonce.
ENDMETHOD.
METHOD run.
DATA: lv_response TYPE string,
lv_method TYPE string,
lv_cnonce TYPE string,
lv_uri TYPE string,
lv_auth TYPE string.
ASSERT NOT mv_nonce IS INITIAL.
lv_method = ii_client->request->get_header_field( '~request_method' ).
lv_uri = ii_client->request->get_header_field( '~request_uri' ).
CALL FUNCTION 'GENERAL_GET_RANDOM_STRING'
EXPORTING
number_chars = 24
IMPORTING
random_string = lv_cnonce.
lv_response = hash(
iv_qop = mv_qop
iv_nonce = mv_nonce
iv_uri = lv_uri
iv_method = lv_method
iv_cnonse = lv_cnonce ).
lv_auth = |Digest username="{ mv_username
}", realm="{ mv_realm
}", nonce="{ mv_nonce
}", uri="{ lv_uri
}", qop={ mv_qop
}, nc={ gv_nc
}, cnonce="{ lv_cnonce
}", response="{ lv_response }"|.
ii_client->request->set_header_field(
name = 'Authorization'
value = lv_auth ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_http IMPLEMENTATION.
METHOD acquire_login_details.
DATA: lv_default_user TYPE string,
lv_user TYPE string,
lv_pass TYPE string,
lo_digest TYPE REF TO zcl_abapgit_http_digest.
lv_default_user = zcl_abapgit_persistence_user=>get_instance( )->get_repo_login( iv_url ).
lv_user = lv_default_user.
zcl_abapgit_password_dialog=>popup(
EXPORTING
iv_repo_url = iv_url
CHANGING
cv_user = lv_user
cv_pass = lv_pass ).
IF lv_user IS INITIAL.
zcx_abapgit_exception=>raise( 'HTTP 401, unauthorized' ).
ENDIF.
IF lv_user <> lv_default_user.
zcl_abapgit_persistence_user=>get_instance( )->set_repo_login(
iv_url = iv_url
iv_login = lv_user ).
ENDIF.
" Offer two factor authentication if it is available and required
zcl_abapgit_2fa_auth_registry=>use_2fa_if_required(
EXPORTING
iv_url = iv_url
CHANGING
cv_username = lv_user
cv_password = lv_pass ).
rv_scheme = ii_client->response->get_header_field( 'www-authenticate' ).
FIND REGEX '^(\w+)' IN rv_scheme SUBMATCHES rv_scheme.
CASE rv_scheme.
WHEN c_scheme-digest.
CREATE OBJECT lo_digest
EXPORTING
ii_client = ii_client
iv_username = lv_user
iv_password = lv_pass.
lo_digest->run( ii_client ).
io_client->set_digest( lo_digest ).
WHEN OTHERS.
ii_client->authenticate(
username = lv_user
password = lv_pass ).
ENDCASE.
ENDMETHOD. "acquire_login_details
METHOD check_auth_requested.
DATA: lv_code TYPE i.
ii_client->response->get_status(
IMPORTING
code = lv_code ).
IF lv_code = 401.
rv_auth_requested = abap_true.
ENDIF.
ENDMETHOD. "check_auth_requested
METHOD create_by_url.
DATA: lv_uri TYPE string,
lv_scheme TYPE string,
li_client TYPE REF TO if_http_client,
lo_proxy_configuration TYPE REF TO zcl_abapgit_proxy_config,
lv_text TYPE string.
CREATE OBJECT lo_proxy_configuration.
li_client = zcl_abapgit_exit=>get_instance( )->create_http_client( iv_url ).
IF li_client IS NOT BOUND.
cl_http_client=>create_by_url(
EXPORTING
url = zcl_abapgit_url=>host( iv_url )
ssl_id = 'ANONYM'
proxy_host = lo_proxy_configuration->get_proxy_url( iv_url )
proxy_service = lo_proxy_configuration->get_proxy_port( iv_url )
IMPORTING
client = li_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
CASE sy-subrc.
WHEN 1.
" make sure:
" a) SSL is setup properly in STRUST
lv_text = 'HTTPS ARGUMENT_NOT_FOUND | STRUST/SSL Setup correct?'.
WHEN OTHERS.
lv_text = 'While creating HTTP Client'. "#EC NOTEXT
ENDCASE.
zcx_abapgit_exception=>raise( lv_text ).
ENDIF.
ENDIF.
IF lo_proxy_configuration->get_proxy_authentication( iv_url ) = abap_true.
zcl_abapgit_proxy_auth=>run( li_client ).
ENDIF.
CREATE OBJECT ro_client
EXPORTING
ii_client = li_client.
IF is_local_system( iv_url ) = abap_true.
li_client->send_sap_logon_ticket( ).
ENDIF.
li_client->request->set_cdata( '' ).
li_client->request->set_header_field(
name = '~request_method'
value = 'GET' ).
li_client->request->set_header_field(
name = 'user-agent'
value = get_agent( ) ). "#EC NOTEXT
lv_uri = zcl_abapgit_url=>path_name( iv_url ) &&
'/info/refs?service=git-' &&
iv_service &&
'-pack'.
li_client->request->set_header_field(
name = '~request_uri'
value = lv_uri ).
" Disable internal auth dialog (due to its unclarity)
li_client->propertytype_logon_popup = if_http_client=>co_disabled.
zcl_abapgit_login_manager=>load( iv_uri = iv_url
ii_client = li_client ).
zcl_abapgit_exit=>get_instance( )->http_client( li_client ).
ro_client->send_receive( ).
IF check_auth_requested( li_client ) = abap_true.
lv_scheme = acquire_login_details( ii_client = li_client
io_client = ro_client
iv_url = iv_url ).
ro_client->send_receive( ).
ENDIF.
ro_client->check_http_200( ).
IF lv_scheme <> c_scheme-digest.
zcl_abapgit_login_manager=>save( iv_uri = iv_url
ii_client = li_client ).
ENDIF.
ENDMETHOD.
METHOD get_agent.
rv_agent = |git/2.0 (abapGit { zif_abapgit_version=>gc_abap_version })|.
ENDMETHOD.
METHOD is_local_system.
DATA: lv_host TYPE string,
lt_list TYPE zif_abapgit_exit=>ty_icm_sinfo2_tt,
li_exit TYPE REF TO zif_abapgit_exit.
FIELD-SYMBOLS: <ls_list> LIKE LINE OF lt_list.
CALL FUNCTION 'ICM_GET_INFO2'
TABLES
servlist = lt_list
EXCEPTIONS
icm_error = 1
icm_timeout = 2
OTHERS = 3.
IF sy-subrc <> 0.
RETURN.
ENDIF.
APPEND INITIAL LINE TO lt_list ASSIGNING <ls_list>.
<ls_list>-hostname = 'localhost'.
li_exit = zcl_abapgit_exit=>get_instance( ).
li_exit->change_local_host( CHANGING ct_hosts = lt_list ).
FIND REGEX 'https?://([^/^:]*)' IN iv_url
SUBMATCHES lv_host.
READ TABLE lt_list WITH KEY hostname = lv_host TRANSPORTING NO FIELDS.
rv_bool = boolc( sy-subrc = 0 ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_2FA_GITHUB_AUTH IMPLEMENTATION.
METHOD constructor.
DATA: lv_match TYPE string.
IF iv_override IS SUPPLIED.
lv_match = iv_override.
ELSE.
lv_match = '^https?://(www\.)?github.com.*$'.
ENDIF.
super->constructor( lv_match ).
ENDMETHOD.
METHOD get_authenticated_client.
DATA: lv_http_code TYPE i,
lv_http_code_description TYPE string.
" If there is a cached client return it instead
IF is_session_running( ) = abap_true AND mi_authenticated_session IS BOUND.
ri_client = mi_authenticated_session.
RETURN.
ENDIF.
" Try to login to GitHub API with username, password and 2fa token
ri_client = get_http_client_for_url( mv_github_api_url ).
" https://developer.github.com/v3/auth/#working-with-two-factor-authentication
ri_client->propertytype_accept_cookie = if_http_client=>co_enabled.
ri_client->request->set_header_field( name = c_otp_header_name value = iv_2fa_token ).
ri_client->authenticate( username = iv_username password = iv_password ).
ri_client->propertytype_logon_popup = if_http_client=>co_disabled.
ri_client->send( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
ri_client->receive( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
" Check if authentication has succeeded
ri_client->response->get_status(
IMPORTING
code = lv_http_code
reason = lv_http_code_description ).
IF lv_http_code <> 200.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_auth_failed
EXPORTING
mv_text = |Authentication failed: { lv_http_code_description }|.
ENDIF.
" Cache the authenticated http session / client to avoid unnecessary additional authentication
IF is_session_running( ) = abap_true.
mi_authenticated_session = ri_client.
ENDIF.
ENDMETHOD.
METHOD get_tobedel_tokens_from_resp.
CONSTANTS: lc_search_regex TYPE string
VALUE `\{"id": ?(\d+)[^\{]*"app":\{[^\{^\}]*\}[^\{]*"fingerprint": ?` &
`"abapGit2FA"[^\{]*\}`.
DATA: lv_response TYPE string,
lo_regex TYPE REF TO cl_abap_regex,
lo_matcher TYPE REF TO cl_abap_matcher.
lv_response = cl_abap_codepage=>convert_from( ii_response->get_data( ) ).
CREATE OBJECT lo_regex
EXPORTING
pattern = lc_search_regex.
lo_matcher = lo_regex->create_matcher( text = lv_response ).
WHILE lo_matcher->find_next( ) = abap_true.
APPEND lo_matcher->get_submatch( 1 ) TO rt_ids.
ENDWHILE.
ENDMETHOD.
METHOD get_token_from_response.
CONSTANTS: lc_search_regex TYPE string VALUE `.*"token":"([^"]*).*$`.
DATA: lv_response TYPE string,
lo_regex TYPE REF TO cl_abap_regex,
lo_matcher TYPE REF TO cl_abap_matcher.
lv_response = cl_abap_codepage=>convert_from( ii_response->get_data( ) ).
CREATE OBJECT lo_regex
EXPORTING
pattern = lc_search_regex.
lo_matcher = lo_regex->create_matcher( text = lv_response ).
IF lo_matcher->match( ) = abap_true.
rv_token = lo_matcher->get_submatch( 1 ).
ENDIF.
ENDMETHOD.
METHOD set_del_token_request.
DATA: lv_url TYPE string.
lv_url = |{ c_restendpoint_authorizations }/{ iv_token_id }|.
ii_request->set_header_field( name = if_http_header_fields_sap=>request_uri
value = lv_url ).
" Other methods than POST and GET do not have constants unfortunately
" ii_request->set_method( if_http_request=>co_request_method_delete ).
ii_request->set_method( 'DELETE' ).
ENDMETHOD.
METHOD set_list_token_request.
ii_request->set_header_field( name = if_http_header_fields_sap=>request_uri
value = c_restendpoint_authorizations ).
ii_request->set_method( if_http_request=>co_request_method_get ).
ENDMETHOD.
METHOD set_new_token_request.
DATA: lv_json_string TYPE string.
lv_json_string = `{"scopes":["repo"],"note":"Generated by abapGit","fingerprint":"abapGit2FA"}`.
ii_request->set_data( cl_abap_codepage=>convert_to( lv_json_string ) ).
ii_request->set_header_field( name = if_http_header_fields_sap=>request_uri
value = c_restendpoint_authorizations ).
ii_request->set_method( if_http_request=>co_request_method_post ).
ENDMETHOD.
METHOD zif_abapgit_2fa_authenticator~authenticate.
DATA: li_http_client TYPE REF TO if_http_client,
lv_http_code TYPE i,
lv_http_code_description TYPE string.
" 1. Try to login to GitHub API
li_http_client = get_authenticated_client( iv_username = iv_username
iv_password = iv_password
iv_2fa_token = iv_2fa_token ).
" 2. Create an access token which can be used instead of a password
" https://developer.github.com/v3/oauth_authorizations/#create-a-new-authorization
set_new_token_request( li_http_client->request ).
li_http_client->send( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
li_http_client->receive( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
li_http_client->response->get_status(
IMPORTING
code = lv_http_code
reason = lv_http_code_description ).
IF lv_http_code <> 201.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_gen_failed
EXPORTING
mv_text = |Token generation failed: { lv_http_code } { lv_http_code_description }|.
ENDIF.
rv_access_token = get_token_from_response( li_http_client->response ).
IF rv_access_token IS INITIAL.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_gen_failed
EXPORTING
mv_text = 'Token generation failed: parser error' ##NO_TEXT.
ENDIF.
" GitHub might need some time until the new token is ready to use, give it a second
CALL FUNCTION 'RZL_SLEEP'.
ENDMETHOD.
METHOD zif_abapgit_2fa_authenticator~delete_access_tokens.
DATA: li_http_client TYPE REF TO if_http_client,
lv_http_code TYPE i,
lv_http_code_description TYPE string,
lt_tobedeleted_tokens TYPE stringtab.
FIELD-SYMBOLS: <lv_id> TYPE string.
li_http_client = get_authenticated_client( iv_username = iv_username
iv_password = iv_password
iv_2fa_token = iv_2fa_token ).
set_list_token_request( li_http_client->request ).
li_http_client->send( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
li_http_client->receive( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
li_http_client->response->get_status(
IMPORTING
code = lv_http_code
reason = lv_http_code_description ).
IF lv_http_code <> 200.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_del_failed
EXPORTING
mv_text = |Could not fetch current 2FA authorizations: | &&
|{ lv_http_code } { lv_http_code_description }|.
ENDIF.
lt_tobedeleted_tokens = get_tobedel_tokens_from_resp( li_http_client->response ).
LOOP AT lt_tobedeleted_tokens ASSIGNING <lv_id> WHERE table_line IS NOT INITIAL.
set_del_token_request( ii_request = li_http_client->request
iv_token_id = <lv_id> ).
li_http_client->send( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
li_http_client->receive( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
li_http_client->response->get_status(
IMPORTING
code = lv_http_code
reason = lv_http_code_description ).
IF lv_http_code <> 204.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_del_failed
EXPORTING
mv_text = |Could not delete token '{ <lv_id> }': | &&
|{ lv_http_code } { lv_http_code_description }|.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD zif_abapgit_2fa_authenticator~end.
super->end( ).
FREE mi_authenticated_session.
ENDMETHOD.
METHOD zif_abapgit_2fa_authenticator~is_2fa_required.
DATA: li_client TYPE REF TO if_http_client.
li_client = get_http_client_for_url( mv_github_api_url ).
li_client->propertytype_logon_popup = if_http_client=>co_disabled.
" The request needs to use something other than GET and it needs to be send to an endpoint
" to trigger a SMS.
li_client->request->set_header_field( name = if_http_header_fields_sap=>request_uri
value = c_restendpoint_authorizations ).
li_client->request->set_method( if_http_request=>co_request_method_post ).
" Try to authenticate, if 2FA is required there will be a specific response header
li_client->authenticate( username = iv_username password = iv_password ).
li_client->send( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
li_client->receive( EXCEPTIONS OTHERS = 1 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
" The response will either be UNAUTHORIZED or MALFORMED which is both fine.
IF li_client->response->get_header_field( c_otp_header_name ) CP 'required*'.
rv_required = abap_true.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_2FA_AUTH_REGISTRY IMPLEMENTATION.
METHOD class_constructor.
DATA: lt_sub TYPE seo_relkeys,
ls_sub LIKE LINE OF lt_sub,
li_authenticator TYPE REF TO zif_abapgit_2fa_authenticator,
lo_class TYPE REF TO cl_oo_class.
TRY.
lo_class ?= cl_oo_class=>get_instance( 'ZCL_ABAPGIT_2FA_AUTH_BASE' ).
lt_sub = lo_class->get_subclasses( ).
SORT lt_sub BY clsname ASCENDING AS TEXT.
LOOP AT lt_sub INTO ls_sub.
CREATE OBJECT li_authenticator TYPE (ls_sub-clsname).
INSERT li_authenticator INTO TABLE gt_registered_authenticators.
ENDLOOP.
CATCH cx_class_not_existent.
CREATE OBJECT li_authenticator TYPE zcl_abapgit_2fa_github_auth.
INSERT li_authenticator INTO TABLE gt_registered_authenticators.
ENDTRY.
ENDMETHOD.
METHOD get_authenticator_for_url.
FIELD-SYMBOLS: <li_authenticator> LIKE LINE OF gt_registered_authenticators.
LOOP AT gt_registered_authenticators ASSIGNING <li_authenticator>.
IF <li_authenticator>->supports_url( iv_url ) = abap_true.
ri_authenticator = <li_authenticator>.
RETURN.
ENDIF.
ENDLOOP.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_unsupported.
ENDMETHOD.
METHOD is_url_supported.
TRY.
get_authenticator_for_url( iv_url ).
rv_supported = abap_true.
CATCH zcx_abapgit_2fa_unsupported ##NO_HANDLER.
ENDTRY.
ENDMETHOD.
METHOD popup_token.
DATA: lv_returncode TYPE c,
lt_fields TYPE TABLE OF sval.
FIELD-SYMBOLS: <ls_field> LIKE LINE OF lt_fields.
APPEND INITIAL LINE TO lt_fields ASSIGNING <ls_field>.
<ls_field>-tabname = 'TADIR'.
<ls_field>-fieldname = 'OBJ_NAME'.
<ls_field>-fieldtext = 'Two factor auth. token'.
CALL FUNCTION 'POPUP_GET_VALUES'
EXPORTING
no_value_check = abap_true
popup_title = 'Two factor auth. token'
IMPORTING
returncode = lv_returncode
TABLES
fields = lt_fields
EXCEPTIONS
error_in_fields = 1
OTHERS = 2. "#EC NOTEXT
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Error from POPUP_GET_VALUES' ).
ENDIF.
IF lv_returncode = 'A'.
zcx_abapgit_exception=>raise( 'Authentication cancelled' ).
ENDIF.
READ TABLE lt_fields INDEX 1 ASSIGNING <ls_field>.
ASSERT sy-subrc = 0.
rv_token = <ls_field>-value.
ENDMETHOD.
METHOD use_2fa_if_required.
DATA: li_authenticator TYPE REF TO zif_abapgit_2fa_authenticator,
lv_2fa_token TYPE string,
lv_access_token TYPE string,
lx_ex TYPE REF TO cx_root.
IF is_url_supported( iv_url ) = abap_false.
RETURN.
ENDIF.
TRY.
li_authenticator = get_authenticator_for_url( iv_url ).
li_authenticator->begin( ).
" Is two factor authentication required for this account?
IF li_authenticator->is_2fa_required( iv_url = iv_url
iv_username = cv_username
iv_password = cv_password ) = abap_true.
lv_2fa_token = popup_token( ).
" Delete an old access token if it exists
li_authenticator->delete_access_tokens( iv_url = iv_url
iv_username = cv_username
iv_password = cv_password
iv_2fa_token = lv_2fa_token ).
" Get a new access token
lv_access_token = li_authenticator->authenticate( iv_url = iv_url
iv_username = cv_username
iv_password = cv_password
iv_2fa_token = lv_2fa_token ).
" Use the access token instead of the password
cv_password = lv_access_token.
ENDIF.
li_authenticator->end( ).
CATCH zcx_abapgit_2fa_error INTO lx_ex.
TRY.
li_authenticator->end( ).
CATCH zcx_abapgit_2fa_illegal_state ##NO_HANDLER.
ENDTRY.
zcx_abapgit_exception=>raise( |2FA error: { lx_ex->get_text( ) }| ).
ENDTRY.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_2fa_auth_base IMPLEMENTATION.
METHOD constructor.
CREATE OBJECT mo_url_regex
EXPORTING
pattern = iv_supported_url_regex
ignore_case = abap_true.
ENDMETHOD.
METHOD is_session_running.
rv_running = mv_session_running.
ENDMETHOD.
METHOD raise_comm_error_from_sy.
DATA: lv_error_msg TYPE string.
MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno
WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4
INTO lv_error_msg.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_comm_error
EXPORTING
mv_text = |Communication error: { lv_error_msg }| ##NO_TEXT.
ENDMETHOD.
METHOD authenticate.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_auth_failed. " Needs to be overwritten in subclasses
ENDMETHOD.
METHOD begin.
IF mv_session_running = abap_true.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_illegal_state.
ENDIF.
mv_session_running = abap_true.
ENDMETHOD.
METHOD delete_access_tokens.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_del_failed. " Needs to be overwritten in subclasses
ENDMETHOD.
METHOD end.
IF mv_session_running = abap_false.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_illegal_state.
ENDIF.
mv_session_running = abap_false.
ENDMETHOD.
METHOD is_2fa_required.
rv_required = abap_false.
ENDMETHOD.
METHOD supports_url.
rv_supported = mo_url_regex->create_matcher( text = iv_url )->match( ).
ENDMETHOD.
METHOD get_http_client_for_url.
DATA: lo_proxy TYPE REF TO zcl_abapgit_proxy_config,
lo_abapgit_exc TYPE REF TO zcx_abapgit_exception,
lv_error_text TYPE string.
CREATE OBJECT lo_proxy.
cl_http_client=>create_by_url(
EXPORTING
url = iv_url
ssl_id = 'ANONYM'
proxy_host = lo_proxy->get_proxy_url( iv_url )
proxy_service = lo_proxy->get_proxy_port( iv_url )
IMPORTING
client = ri_client
EXCEPTIONS
argument_not_found = 1
plugin_not_active = 2
internal_error = 3
OTHERS = 4 ).
IF sy-subrc <> 0.
raise_comm_error_from_sy( ).
ENDIF.
IF lo_proxy->get_proxy_authentication( iv_url ) = abap_true.
TRY.
zcl_abapgit_proxy_auth=>run( ri_client ).
CATCH zcx_abapgit_exception INTO lo_abapgit_exc.
lv_error_text = lo_abapgit_exc->get_text( ).
IF lv_error_text IS INITIAL.
lv_error_text = `Proxy authentication error`.
ENDIF.
RAISE EXCEPTION TYPE zcx_abapgit_2fa_comm_error EXPORTING mv_text = lv_error_text previous = lo_abapgit_exc.
ENDTRY.
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_TAG IMPLEMENTATION.
METHOD add_tag_prefix.
rv_text = zif_abapgit_definitions=>c_tag_prefix && iv_text.
ENDMETHOD.
METHOD remove_tag_prefix.
rv_text = iv_text.
REPLACE FIRST OCCURRENCE OF zif_abapgit_definitions=>c_tag_prefix
IN rv_text
WITH ''.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GIT_UTILS IMPLEMENTATION.
METHOD get_null.
DATA: lv_x(4) TYPE x VALUE '00000000',
lv_z(2) TYPE c.
FIELD-SYMBOLS <lv_y> TYPE c.
ASSIGN lv_x TO <lv_y> CASTING.
lv_z = <lv_y>.
rv_c = lv_z(1).
ENDMETHOD.
METHOD length_utf8_hex.
DATA: lv_xstring TYPE xstring,
lv_string TYPE string,
lv_char4 TYPE c LENGTH 4,
lv_x TYPE x LENGTH 2,
lo_obj TYPE REF TO cl_abap_conv_in_ce,
lv_len TYPE int4.
lv_xstring = iv_data(4).
lo_obj = cl_abap_conv_in_ce=>create(
input = lv_xstring
encoding = 'UTF-8' ).
lv_len = xstrlen( lv_xstring ).
TRY.
lo_obj->read( EXPORTING n = lv_len
IMPORTING data = lv_string ).
CATCH cx_sy_conversion_codepage.
zcx_abapgit_exception=>raise( 'error converting to hex, LENGTH_UTF8_HEX' ).
ENDTRY.
lv_char4 = lv_string.
TRANSLATE lv_char4 TO UPPER CASE.
lv_x = lv_char4.
rv_len = lv_x.
ENDMETHOD.
METHOD pkt_string.
DATA: lv_x TYPE x,
lv_len TYPE i.
lv_len = strlen( iv_string ).
IF lv_len >= 255.
zcx_abapgit_exception=>raise( 'PKT, todo' ).
ENDIF.
lv_x = lv_len + 4.
rv_pkt = rv_pkt && '00' && lv_x && iv_string.
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_git_transport IMPLEMENTATION.
METHOD branches.
DATA: lo_client TYPE REF TO zcl_abapgit_http_client.
branch_list(
EXPORTING
iv_url = iv_url
iv_service = c_service-upload
IMPORTING
eo_client = lo_client
eo_branch_list = ro_branch_list ).
lo_client->close( ).
ENDMETHOD.
METHOD branch_list.
DATA: lv_data TYPE string.
eo_client = zcl_abapgit_http=>create_by_url(
iv_url = iv_url
iv_service = iv_service ).
lv_data = eo_client->get_cdata( ).
CREATE OBJECT eo_branch_list
EXPORTING
iv_data = lv_data.
ENDMETHOD.
METHOD find_branch.
branch_list(
EXPORTING
iv_url = iv_url
iv_service = iv_service
IMPORTING
eo_client = eo_client
eo_branch_list = eo_branch_list ).
IF ev_branch IS SUPPLIED.
ev_branch = eo_branch_list->find_by_name( iv_branch_name )-sha1.
ENDIF.
ENDMETHOD.
METHOD parse.
CONSTANTS: lc_band1 TYPE x VALUE '01'.
DATA: lv_len TYPE i,
lv_contents TYPE xstring,
lv_pack TYPE xstring.
WHILE xstrlen( cv_data ) >= 4.
lv_len = zcl_abapgit_git_utils=>length_utf8_hex( cv_data ).
IF lv_len > xstrlen( cv_data ).
zcx_abapgit_exception=>raise( 'parse, string length too large' ).
ENDIF.
lv_contents = cv_data(lv_len).
IF lv_len = 0.
cv_data = cv_data+4.
CONTINUE.
ELSE.
cv_data = cv_data+lv_len.
ENDIF.
lv_contents = lv_contents+4.
IF xstrlen( lv_contents ) > 1 AND lv_contents(1) = lc_band1.
CONCATENATE lv_pack lv_contents+1 INTO lv_pack IN BYTE MODE.
ENDIF.
ENDWHILE.
ev_pack = lv_pack.
ENDMETHOD.
METHOD receive_pack.
DATA: lo_client TYPE REF TO zcl_abapgit_http_client,
lv_cmd_pkt TYPE string,
lv_line TYPE string,
lv_tmp TYPE xstring,
lv_xstring TYPE xstring,
lv_string TYPE string,
lv_cap_list TYPE string,
lv_buffer TYPE string.
find_branch(
EXPORTING
iv_url = iv_url
iv_service = c_service-receive
iv_branch_name = iv_branch_name
IMPORTING
eo_client = lo_client ).
lo_client->set_headers(
iv_url = iv_url
iv_service = c_service-receive ).
lv_cap_list = 'report-status' ##NO_TEXT.
lv_line = iv_old &&
` ` &&
iv_new &&
` ` &&
iv_branch_name &&
zcl_abapgit_git_utils=>get_null( ) &&
` ` &&
lv_cap_list &&
zif_abapgit_definitions=>c_newline. "#EC NOTEXT
lv_cmd_pkt = zcl_abapgit_git_utils=>pkt_string( lv_line ).
lv_buffer = lv_cmd_pkt && '0000'.
lv_tmp = zcl_abapgit_convert=>string_to_xstring_utf8( lv_buffer ).
CONCATENATE lv_tmp iv_pack INTO lv_xstring IN BYTE MODE.
lv_xstring = lo_client->send_receive_close( lv_xstring ).
lv_string = zcl_abapgit_convert=>xstring_to_string_utf8( lv_xstring ).
IF NOT lv_string CP '*unpack ok*'.
zcx_abapgit_exception=>raise( 'unpack not ok' ).
ELSEIF lv_string CP '*pre-receive hook declined*'.
zcx_abapgit_exception=>raise( 'pre-receive hook declined' ).
ELSEIF lv_string CP '*push declined due to email privacy*'.
zcx_abapgit_exception=>raise( 'push declined due to email privacy' ).
ELSEIF lv_string CP '*funny refname*'.
zcx_abapgit_exception=>raise( 'funny refname' ).
ELSEIF lv_string CP '*failed to update ref*'.
zcx_abapgit_exception=>raise( 'failed to update ref' ).
ELSEIF lv_string CP '*missing necessary objects*'.
zcx_abapgit_exception=>raise( 'missing necessary objects' ).
ENDIF.
ENDMETHOD.
METHOD upload_pack.
DATA: lo_client TYPE REF TO zcl_abapgit_http_client,
lv_buffer TYPE string,
lv_xstring TYPE xstring,
lv_line TYPE string,
lv_pack TYPE xstring,
lt_branches TYPE zif_abapgit_definitions=>ty_git_branch_list_tt,
lv_capa TYPE string.
FIELD-SYMBOLS: <ls_branch> LIKE LINE OF lt_branches.
CLEAR: et_objects,
ev_branch,
eo_branch_list.
find_branch(
EXPORTING
iv_url = iv_url
iv_service = c_service-upload
iv_branch_name = iv_branch_name
IMPORTING
eo_client = lo_client
eo_branch_list = eo_branch_list
ev_branch = ev_branch ).
IF it_branches IS INITIAL.
APPEND INITIAL LINE TO lt_branches ASSIGNING <ls_branch>.
<ls_branch>-sha1 = ev_branch.
ELSE.
lt_branches = it_branches.
ENDIF.
lo_client->set_headers( iv_url = iv_url
iv_service = c_service-upload ).
LOOP AT lt_branches FROM 1 ASSIGNING <ls_branch>.
IF sy-tabix = 1.
lv_capa = 'side-band-64k no-progress multi_ack' ##NO_TEXT.
lv_line = 'want' && ` ` && <ls_branch>-sha1
&& ` ` && lv_capa && zif_abapgit_definitions=>c_newline. "#EC NOTEXT
ELSE.
lv_line = 'want' && ` ` && <ls_branch>-sha1
&& zif_abapgit_definitions=>c_newline. "#EC NOTEXT
ENDIF.
lv_buffer = lv_buffer && zcl_abapgit_git_utils=>pkt_string( lv_line ).
ENDLOOP.
IF iv_deepen = abap_true.
lv_buffer = lv_buffer && zcl_abapgit_git_utils=>pkt_string( 'deepen 1'
&& zif_abapgit_definitions=>c_newline ). "#EC NOTEXT
ENDIF.
lv_buffer = lv_buffer
&& '0000'
&& '0009done' && zif_abapgit_definitions=>c_newline.
lv_xstring = lo_client->send_receive_close(
zcl_abapgit_convert=>string_to_xstring_utf8( lv_buffer ) ).
parse( IMPORTING ev_pack = lv_pack
CHANGING cv_data = lv_xstring ).
IF lv_pack IS INITIAL.
zcx_abapgit_exception=>raise( 'empty pack' ).
ENDIF.
et_objects = zcl_abapgit_git_pack=>decode( lv_pack ).
ENDMETHOD.
ENDCLASS.
CLASS zcl_abapgit_git_porcelain IMPLEMENTATION.
METHOD build_trees.
DATA: lt_nodes TYPE zcl_abapgit_git_pack=>ty_nodes_tt,
ls_tree LIKE LINE OF rt_trees,
lv_len TYPE i,
lt_folders TYPE ty_folders_tt.
FIELD-SYMBOLS: <ls_folder> LIKE LINE OF lt_folders,
<ls_node> LIKE LINE OF lt_nodes,
<ls_sub> LIKE LINE OF lt_folders,
<ls_exp> LIKE LINE OF it_expanded.
lt_folders = find_folders( it_expanded ).
SORT lt_folders BY count DESCENDING.
LOOP AT lt_folders ASSIGNING <ls_folder>.
CLEAR lt_nodes.
LOOP AT it_expanded ASSIGNING <ls_exp> WHERE path = <ls_folder>-path.
APPEND INITIAL LINE TO lt_nodes ASSIGNING <ls_node>.
<ls_node>-chmod = <ls_exp>-chmod.
<ls_node>-name = <ls_exp>-name.
<ls_node>-sha1 = <ls_exp>-sha1.
ENDLOOP.
LOOP AT lt_folders ASSIGNING <ls_sub> WHERE count = <ls_folder>-count + 1.
lv_len = strlen( <ls_folder>-path ).
IF strlen( <ls_sub>-path ) > lv_len AND <ls_sub>-path(lv_len) = <ls_folder>-path.
APPEND INITIAL LINE TO lt_nodes ASSIGNING <ls_node>.
<ls_node>-chmod = zif_abapgit_definitions=>c_chmod-dir.
<ls_node>-name = <ls_sub>-path+lv_len.
lv_len = strlen( <ls_node>-name ) - 1.
<ls_node>-name = <ls_node>-name(lv_len).
<ls_node>-sha1 = <ls_sub>-sha1.
ENDIF.
ENDLOOP.
CLEAR ls_tree.
ls_tree-path = <ls_folder>-path.
ls_tree-data = zcl_abapgit_git_pack=>encode_tree( lt_nodes ).
ls_tree-sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>c_type-tree iv_data = ls_tree-data ).
APPEND ls_tree TO rt_trees.
<ls_folder>-sha1 = ls_tree-sha1.
ENDLOOP.
ENDMETHOD.
METHOD create_annotated_tag.
receive_pack_create_tag(
is_tag = is_tag
iv_url = iv_url ).
ENDMETHOD.
METHOD create_branch.
DATA: lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt,
lv_pack TYPE xstring.
IF iv_name CS ` `.
zcx_abapgit_exception=>raise( 'Branch name cannot contain blank spaces' ).
ENDIF.
lv_pack = zcl_abapgit_git_pack=>encode( lt_objects ).
zcl_abapgit_git_transport=>receive_pack(
iv_url = iv_url
iv_old = c_zero
iv_new = iv_from
iv_branch_name = iv_name
iv_pack = lv_pack ).
ENDMETHOD.
METHOD create_lightweight_tag.
DATA: lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt,
lv_pack TYPE xstring.
lv_pack = zcl_abapgit_git_pack=>encode( lt_objects ).
zcl_abapgit_git_transport=>receive_pack(
iv_url = iv_url
iv_old = c_zero
iv_new = is_tag-sha1
iv_branch_name = is_tag-name
iv_pack = lv_pack ).
ENDMETHOD.
METHOD create_tag.
IF is_tag-name CS ` `.
zcx_abapgit_exception=>raise( 'Tag name cannot contain blank spaces' ).
ENDIF.
CASE is_tag-type.
WHEN zif_abapgit_definitions=>c_git_branch_type-annotated_tag.
create_annotated_tag(
is_tag = is_tag
iv_url = iv_url ).
WHEN zif_abapgit_definitions=>c_git_branch_type-lightweight_tag.
create_lightweight_tag(
is_tag = is_tag
iv_url = iv_url ).
WHEN OTHERS.
zcx_abapgit_exception=>raise( |Invalid tag type: { is_tag-type }| ).
ENDCASE.
ENDMETHOD.
METHOD delete_branch.
DATA: lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt,
lv_pack TYPE xstring.
lv_pack = zcl_abapgit_git_pack=>encode( lt_objects ).
zcl_abapgit_git_transport=>receive_pack(
iv_url = iv_url
iv_old = is_branch-sha1
iv_new = c_zero
iv_branch_name = is_branch-name
iv_pack = lv_pack ).
ENDMETHOD.
METHOD delete_tag.
DATA: lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt,
lv_pack TYPE xstring.
lv_pack = zcl_abapgit_git_pack=>encode( lt_objects ).
zcl_abapgit_git_transport=>receive_pack(
iv_url = iv_url
iv_old = is_tag-sha1
iv_new = c_zero
iv_branch_name = is_tag-name
iv_pack = lv_pack ).
ENDMETHOD.
METHOD find_folders.
DATA: lt_paths TYPE TABLE OF string,
lv_split TYPE string,
lv_path TYPE string.
FIELD-SYMBOLS: <ls_folder> LIKE LINE OF rt_folders,
<ls_new> LIKE LINE OF rt_folders,
<ls_exp> LIKE LINE OF it_expanded.
LOOP AT it_expanded ASSIGNING <ls_exp>.
READ TABLE rt_folders WITH KEY path = <ls_exp>-path TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
APPEND INITIAL LINE TO rt_folders ASSIGNING <ls_folder>.
<ls_folder>-path = <ls_exp>-path.
ENDIF.
ENDLOOP.
LOOP AT rt_folders ASSIGNING <ls_folder>.
SPLIT <ls_folder>-path AT '/' INTO TABLE lt_paths.
CLEAR lv_path.
LOOP AT lt_paths INTO lv_split.
CONCATENATE lv_path lv_split '/' INTO lv_path.
READ TABLE rt_folders WITH KEY path = lv_path TRANSPORTING NO FIELDS.
IF sy-subrc <> 0.
APPEND INITIAL LINE TO rt_folders ASSIGNING <ls_new>.
<ls_new>-path = lv_path.
ENDIF.
ENDLOOP.
ENDLOOP.
LOOP AT rt_folders ASSIGNING <ls_folder>.
FIND ALL OCCURRENCES OF '/' IN <ls_folder>-path MATCH COUNT <ls_folder>-count.
ENDLOOP.
ENDMETHOD.
METHOD full_tree.
DATA: ls_object LIKE LINE OF it_objects,
ls_commit TYPE zcl_abapgit_git_pack=>ty_commit.
READ TABLE it_objects INTO ls_object
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-commit
sha1 = iv_branch .
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'commit not found' ).
ENDIF.
ls_commit = zcl_abapgit_git_pack=>decode_commit( ls_object-data ).
rt_expanded = walk_tree( it_objects = it_objects
iv_tree = ls_commit-tree
iv_base = '/' ).
ENDMETHOD.
METHOD pull.
DATA: ls_object LIKE LINE OF rs_result-objects,
ls_commit TYPE zcl_abapgit_git_pack=>ty_commit.
zcl_abapgit_git_transport=>upload_pack(
EXPORTING
iv_url = iv_url
iv_branch_name = iv_branch_name
IMPORTING
et_objects = rs_result-objects
ev_branch = rs_result-branch ).
READ TABLE rs_result-objects INTO ls_object
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-commit
sha1 = rs_result-branch.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Commit/branch not found' ).
ENDIF.
ls_commit = zcl_abapgit_git_pack=>decode_commit( ls_object-data ).
walk( EXPORTING it_objects = rs_result-objects
iv_sha1 = ls_commit-tree
iv_path = '/'
CHANGING ct_files = rs_result-files ).
ENDMETHOD.
METHOD push.
DATA: lt_expanded TYPE zif_abapgit_definitions=>ty_expanded_tt,
lt_blobs TYPE zif_abapgit_definitions=>ty_files_tt,
lv_sha1 TYPE zif_abapgit_definitions=>ty_sha1,
lv_new_tree TYPE zif_abapgit_definitions=>ty_sha1,
lt_trees TYPE ty_trees_tt,
lt_stage TYPE zcl_abapgit_stage=>ty_stage_tt.
FIELD-SYMBOLS: <ls_stage> LIKE LINE OF lt_stage,
<ls_updated> LIKE LINE OF rs_result-updated_files,
<ls_exp> LIKE LINE OF lt_expanded.
lt_expanded = full_tree( it_objects = it_old_objects
iv_branch = iv_parent ).
lt_stage = io_stage->get_all( ).
LOOP AT lt_stage ASSIGNING <ls_stage>.
" Save file ref to updated files table
APPEND INITIAL LINE TO rs_result-updated_files ASSIGNING <ls_updated>.
MOVE-CORRESPONDING <ls_stage>-file TO <ls_updated>.
CASE <ls_stage>-method.
WHEN zcl_abapgit_stage=>c_method-add.
APPEND <ls_stage>-file TO lt_blobs.
READ TABLE lt_expanded ASSIGNING <ls_exp> WITH KEY
name = <ls_stage>-file-filename
path = <ls_stage>-file-path.
IF sy-subrc <> 0. " new files
APPEND INITIAL LINE TO lt_expanded ASSIGNING <ls_exp>.
<ls_exp>-name = <ls_stage>-file-filename.
<ls_exp>-path = <ls_stage>-file-path.
<ls_exp>-chmod = zif_abapgit_definitions=>c_chmod-file.
ENDIF.
lv_sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>c_type-blob
iv_data = <ls_stage>-file-data ).
IF <ls_exp>-sha1 <> lv_sha1.
<ls_exp>-sha1 = lv_sha1.
ENDIF.
<ls_updated>-sha1 = lv_sha1. "New sha1
WHEN zcl_abapgit_stage=>c_method-rm.
DELETE lt_expanded
WHERE name = <ls_stage>-file-filename
AND path = <ls_stage>-file-path.
ASSERT sy-subrc = 0.
CLEAR <ls_updated>-sha1. " Mark as deleted
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'stage method not supported, todo' ).
ENDCASE.
ENDLOOP.
lt_trees = build_trees( lt_expanded ).
receive_pack_push(
EXPORTING
is_comment = is_comment
it_trees = lt_trees
iv_branch_name = iv_branch_name
iv_url = iv_url
iv_parent = iv_parent
iv_parent2 = io_stage->get_merge_source( )
it_blobs = lt_blobs
IMPORTING
ev_new_commit = rs_result-branch
et_new_objects = rs_result-new_objects
ev_new_tree = lv_new_tree ).
APPEND LINES OF it_old_objects TO rs_result-new_objects.
walk( EXPORTING it_objects = rs_result-new_objects
iv_sha1 = lv_new_tree
iv_path = '/'
CHANGING ct_files = rs_result-new_files ).
ENDMETHOD.
METHOD receive_pack_create_tag.
DATA: lv_tag TYPE xstring,
lt_objects TYPE zif_abapgit_definitions=>ty_objects_tt,
lv_pack TYPE xstring,
ls_object LIKE LINE OF lt_objects,
ls_tag TYPE zcl_abapgit_git_pack=>ty_tag,
lv_new_tag_sha1 TYPE zif_abapgit_definitions=>ty_sha1.
ls_tag-object = is_tag-sha1.
ls_tag-type = zif_abapgit_definitions=>c_type-commit.
ls_tag-tag = is_tag-name.
ls_tag-tagger_name = is_tag-tagger_name.
ls_tag-tagger_email = is_tag-tagger_email.
ls_tag-message = is_tag-message
&& |{ zif_abapgit_definitions=>c_newline }|
&& |{ zif_abapgit_definitions=>c_newline }|
&& is_tag-body.
lv_tag = zcl_abapgit_git_pack=>encode_tag( ls_tag ).
lv_new_tag_sha1 = zcl_abapgit_hash=>sha1(
iv_type = zif_abapgit_definitions=>c_type-tag
iv_data = lv_tag ).
CLEAR ls_object.
ls_object-sha1 = lv_new_tag_sha1.
ls_object-type = zif_abapgit_definitions=>c_type-tag.
ls_object-data = lv_tag.
ls_object-index = 1.
APPEND ls_object TO lt_objects.
lv_pack = zcl_abapgit_git_pack=>encode( lt_objects ).
zcl_abapgit_git_transport=>receive_pack(
iv_url = iv_url
iv_old = c_zero
iv_new = lv_new_tag_sha1
iv_branch_name = is_tag-name
iv_pack = lv_pack ).
ENDMETHOD.
METHOD receive_pack_push.
DATA: lv_time TYPE zcl_abapgit_time=>ty_unixtime,
lv_commit TYPE xstring,
lv_pack TYPE xstring,
ls_object LIKE LINE OF et_new_objects,
ls_commit TYPE zcl_abapgit_git_pack=>ty_commit.
DATA: lv_uindex TYPE sy-index.
FIELD-SYMBOLS: <ls_tree> LIKE LINE OF it_trees,
<ls_blob> LIKE LINE OF it_blobs.
lv_time = zcl_abapgit_time=>get( ).
READ TABLE it_trees ASSIGNING <ls_tree> WITH KEY path = '/'.
ASSERT sy-subrc = 0.
ls_commit-committer = |{ is_comment-committer-name
} <{ is_comment-committer-email }> { lv_time }|.
IF is_comment-author-name IS NOT INITIAL.
ls_commit-author = |{ is_comment-author-name
} <{ is_comment-author-email }> { lv_time }|.
ELSE.
ls_commit-author = ls_commit-committer.
ENDIF.
ls_commit-tree = <ls_tree>-sha1.
ls_commit-parent = iv_parent.
ls_commit-parent2 = iv_parent2.
ls_commit-body = is_comment-comment.
lv_commit = zcl_abapgit_git_pack=>encode_commit( ls_commit ).
CLEAR ls_object.
ls_object-sha1 = zcl_abapgit_hash=>sha1( iv_type = zif_abapgit_definitions=>c_type-commit iv_data = lv_commit ).
ls_object-type = zif_abapgit_definitions=>c_type-commit.
ls_object-data = lv_commit.
APPEND ls_object TO et_new_objects.
LOOP AT it_trees ASSIGNING <ls_tree>.
CLEAR ls_object.
ls_object-sha1 = <ls_tree>-sha1.
READ TABLE et_new_objects
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-tree
sha1 = ls_object-sha1
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
CONTINUE.
ENDIF.
ls_object-type = zif_abapgit_definitions=>c_type-tree.
ls_object-data = <ls_tree>-data.
lv_uindex = lv_uindex + 1.
ls_object-index = lv_uindex.
APPEND ls_object TO et_new_objects.
ENDLOOP.
LOOP AT it_blobs ASSIGNING <ls_blob>.
CLEAR ls_object.
ls_object-sha1 = zcl_abapgit_hash=>sha1(
iv_type = zif_abapgit_definitions=>c_type-blob
iv_data = <ls_blob>-data ).
READ TABLE et_new_objects
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-blob
sha1 = ls_object-sha1
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
CONTINUE.
ENDIF.
ls_object-type = zif_abapgit_definitions=>c_type-blob.
ASSERT NOT <ls_blob>-data IS INITIAL.
ls_object-data = <ls_blob>-data.
lv_uindex = lv_uindex + 1.
ls_object-index = lv_uindex.
APPEND ls_object TO et_new_objects.
ENDLOOP.
lv_pack = zcl_abapgit_git_pack=>encode( et_new_objects ).
ev_new_commit = zcl_abapgit_hash=>sha1(
iv_type = zif_abapgit_definitions=>c_type-commit
iv_data = lv_commit ).
zcl_abapgit_git_transport=>receive_pack(
iv_url = iv_url
iv_old = iv_parent
iv_new = ev_new_commit
iv_branch_name = iv_branch_name
iv_pack = lv_pack ).
ev_new_tree = ls_commit-tree.
ENDMETHOD.
METHOD walk.
DATA: lv_path TYPE string,
ls_file LIKE LINE OF ct_files,
lt_nodes TYPE zcl_abapgit_git_pack=>ty_nodes_tt.
FIELD-SYMBOLS: <ls_tree> LIKE LINE OF it_objects,
<ls_blob> LIKE LINE OF it_objects,
<ls_node> LIKE LINE OF lt_nodes.
READ TABLE it_objects ASSIGNING <ls_tree>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-tree
sha1 = iv_sha1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Walk, tree not found' ).
ENDIF.
lt_nodes = zcl_abapgit_git_pack=>decode_tree( <ls_tree>-data ).
LOOP AT lt_nodes ASSIGNING <ls_node>.
IF <ls_node>-chmod = zif_abapgit_definitions=>c_chmod-file.
READ TABLE it_objects ASSIGNING <ls_blob>
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-blob
sha1 = <ls_node>-sha1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Walk, blob not found' ).
ENDIF.
CLEAR ls_file.
ls_file-path = iv_path.
ls_file-filename = <ls_node>-name.
ls_file-data = <ls_blob>-data.
ls_file-sha1 = <ls_blob>-sha1.
APPEND ls_file TO ct_files.
ENDIF.
ENDLOOP.
LOOP AT lt_nodes ASSIGNING <ls_node> WHERE chmod = zif_abapgit_definitions=>c_chmod-dir.
CONCATENATE iv_path <ls_node>-name '/' INTO lv_path.
walk( EXPORTING it_objects = it_objects
iv_sha1 = <ls_node>-sha1
iv_path = lv_path
CHANGING ct_files = ct_files ).
ENDLOOP.
ENDMETHOD.
METHOD walk_tree.
DATA: ls_object LIKE LINE OF it_objects,
lt_expanded LIKE rt_expanded,
lt_nodes TYPE zcl_abapgit_git_pack=>ty_nodes_tt.
FIELD-SYMBOLS: <ls_exp> LIKE LINE OF rt_expanded,
<ls_node> LIKE LINE OF lt_nodes.
READ TABLE it_objects INTO ls_object
WITH KEY type COMPONENTS
type = zif_abapgit_definitions=>c_type-tree
sha1 = iv_tree.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'tree not found' ).
ENDIF.
lt_nodes = zcl_abapgit_git_pack=>decode_tree( ls_object-data ).
LOOP AT lt_nodes ASSIGNING <ls_node>.
CASE <ls_node>-chmod.
WHEN zif_abapgit_definitions=>c_chmod-file
OR zif_abapgit_definitions=>c_chmod-executable.
APPEND INITIAL LINE TO rt_expanded ASSIGNING <ls_exp>.
<ls_exp>-path = iv_base.
<ls_exp>-name = <ls_node>-name.
<ls_exp>-sha1 = <ls_node>-sha1.
<ls_exp>-chmod = <ls_node>-chmod.
WHEN zif_abapgit_definitions=>c_chmod-dir.
lt_expanded = walk_tree(
it_objects = it_objects
iv_tree = <ls_node>-sha1
iv_base = iv_base && <ls_node>-name && '/' ).
APPEND LINES OF lt_expanded TO rt_expanded.
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'walk_tree: unknown chmod' ).
ENDCASE.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GIT_PACK IMPLEMENTATION.
METHOD decode.
DATA: lv_x TYPE x,
lv_data TYPE xstring,
lv_type TYPE c LENGTH 6,
lv_zlib TYPE x LENGTH 2,
lv_objects TYPE i,
lv_len TYPE i,
lv_sha1 TYPE zif_abapgit_definitions=>ty_sha1,
lv_ref_delta TYPE zif_abapgit_definitions=>ty_sha1,
lv_compressed_len TYPE i,
lv_compressed TYPE xstring,
lv_decompressed TYPE xstring,
lv_decompress_len TYPE i,
lv_xstring TYPE xstring,
lv_expected TYPE i,
ls_object LIKE LINE OF rt_objects.
DATA: lv_uindex TYPE sy-index.
lv_data = iv_data.
IF NOT xstrlen( lv_data ) > 4 OR lv_data(4) <> c_pack_start.
zcx_abapgit_exception=>raise( 'Unexpected pack header' ).
ENDIF.
lv_data = lv_data+4.
IF lv_data(4) <> c_version.
zcx_abapgit_exception=>raise( 'Version not supported' ).
ENDIF.
lv_data = lv_data+4.
lv_xstring = lv_data(4).
lv_objects = zcl_abapgit_convert=>xstring_to_int( lv_xstring ).
lv_data = lv_data+4.
DO lv_objects TIMES.
lv_uindex = sy-index.
lv_x = lv_data(1).
lv_type = get_type( lv_x ).
get_length( IMPORTING ev_length = lv_expected
CHANGING cv_data = lv_data ).
IF lv_type = zif_abapgit_definitions=>c_type-ref_d.
lv_ref_delta = lv_data(20).
lv_data = lv_data+20.
ENDIF.
lv_zlib = lv_data(2).
IF lv_zlib <> c_zlib AND lv_zlib <> c_zlib_hmm.
zcx_abapgit_exception=>raise( 'Unexpected zlib header' ).
ENDIF.
lv_data = lv_data+2.
IF lv_zlib = c_zlib.
cl_abap_gzip=>decompress_binary(
EXPORTING
gzip_in = lv_data
IMPORTING
raw_out = lv_decompressed
raw_out_len = lv_decompress_len ).
IF lv_expected <> lv_decompress_len.
zcx_abapgit_exception=>raise( 'Decompression falied' ).
ENDIF.
cl_abap_gzip=>compress_binary(
EXPORTING
raw_in = lv_decompressed
IMPORTING
gzip_out = lv_compressed
gzip_out_len = lv_compressed_len ).
IF lv_compressed(lv_compressed_len) <> lv_data(lv_compressed_len).
"Lets try with zlib before error in out for good
"This fixes issues with TFS 2017 and visualstudio.com Git repos
zlib_decompress( CHANGING cv_data = lv_data
cv_decompressed = lv_decompressed ).
ELSE.
lv_data = lv_data+lv_compressed_len.
ENDIF.
ELSEIF lv_zlib = c_zlib_hmm.
zlib_decompress( CHANGING cv_data = lv_data
cv_decompressed = lv_decompressed ).
ENDIF.
CLEAR ls_object.
ls_object-adler32 = lv_data(4).
lv_data = lv_data+4. " skip adler checksum
IF lv_type = zif_abapgit_definitions=>c_type-ref_d.
ls_object-sha1 = lv_ref_delta.
TRANSLATE ls_object-sha1 TO LOWER CASE.
ELSE.
ls_object-sha1 = zcl_abapgit_hash=>sha1(
iv_type = lv_type
iv_data = lv_decompressed ).
ENDIF.
ls_object-type = lv_type.
ls_object-data = lv_decompressed.
ls_object-index = lv_uindex.
APPEND ls_object TO rt_objects.
ENDDO.
lv_len = xstrlen( iv_data ) - 20.
lv_xstring = iv_data(lv_len).
lv_sha1 = zcl_abapgit_hash=>sha1_raw( lv_xstring ).
IF to_upper( lv_sha1 ) <> lv_data.
zcx_abapgit_exception=>raise( 'SHA1 at end of pack doesnt match' ).
ENDIF.
decode_deltas( CHANGING ct_objects = rt_objects ).
ENDMETHOD.
METHOD decode_commit.
DATA: lv_string TYPE string,
lv_word TYPE string,
lv_length TYPE i,
lv_trash TYPE string ##NEEDED,
lt_string TYPE TABLE OF string.
FIELD-SYMBOLS: <lv_string> LIKE LINE OF lt_string.
lv_string = zcl_abapgit_convert=>xstring_to_string_utf8( iv_data ).
SPLIT lv_string AT zif_abapgit_definitions=>c_newline INTO TABLE lt_string.
LOOP AT lt_string ASSIGNING <lv_string>.
lv_length = strlen( <lv_string> ) + 1.
lv_string = lv_string+lv_length.
SPLIT <lv_string> AT space INTO lv_word lv_trash.
CASE lv_word.
WHEN 'tree'.
rs_commit-tree = <lv_string>+5.
WHEN 'parent'.
IF rs_commit-parent IS INITIAL.
rs_commit-parent = <lv_string>+7.
ELSE.
rs_commit-parent2 = <lv_string>+7.
ENDIF.
WHEN 'author'.
rs_commit-author = <lv_string>+7.
WHEN 'committer'.
rs_commit-committer = <lv_string>+10.
EXIT. " current loop
WHEN OTHERS.
ASSERT 0 = 1.
ENDCASE.
ENDLOOP.
rs_commit-body = lv_string+1.
IF rs_commit-author IS INITIAL
OR rs_commit-committer IS INITIAL
OR rs_commit-tree IS INITIAL.
zcx_abapgit_exception=>raise( 'multiple parents? not supported' ).
ENDIF.
ENDMETHOD.
METHOD decode_deltas.
DATA: ls_object LIKE LINE OF ct_objects,
lo_progress TYPE REF TO zcl_abapgit_progress,
lt_deltas LIKE ct_objects.
LOOP AT ct_objects INTO ls_object
USING KEY type
WHERE type = zif_abapgit_definitions=>c_type-ref_d.
INSERT ls_object INTO TABLE lt_deltas.
ENDLOOP.
DELETE ct_objects
USING KEY type
WHERE type = zif_abapgit_definitions=>c_type-ref_d.
"Restore correct Delta Order
SORT lt_deltas BY index.
CREATE OBJECT lo_progress
EXPORTING
iv_total = lines( lt_deltas ).
LOOP AT lt_deltas INTO ls_object.
lo_progress->show( iv_current = sy-tabix
iv_text = 'Decode deltas' ) ##NO_TEXT.
delta( EXPORTING is_object = ls_object
CHANGING ct_objects = ct_objects ).
ENDLOOP.
ENDMETHOD.
METHOD decode_tag.
DATA: lv_string TYPE string,
lv_word TYPE string,
lv_trash TYPE string ##NEEDED,
lt_string TYPE TABLE OF string.
FIELD-SYMBOLS: <lv_string> LIKE LINE OF lt_string.
lv_string = zcl_abapgit_convert=>xstring_to_string_utf8( iv_data ).
SPLIT lv_string AT zif_abapgit_definitions=>c_newline INTO TABLE lt_string.
LOOP AT lt_string ASSIGNING <lv_string>.
SPLIT <lv_string> AT space INTO lv_word lv_trash.
CASE lv_word.
WHEN 'object'.
rs_tag-object = lv_trash.
WHEN 'type'.
rs_tag-type = lv_trash.
WHEN 'tag'.
rs_tag-tag = lv_trash.
WHEN 'tagger'.
FIND FIRST OCCURRENCE OF REGEX `(.*)<(.*)>`
IN lv_trash
SUBMATCHES rs_tag-tagger_name
rs_tag-tagger_email.
rs_tag-tagger_name = condense( rs_tag-tagger_name ).
WHEN ''.
" ignore blank lines
CONTINUE.
WHEN OTHERS.
" these are the non empty line which don't start with a key word
" the first one is the message, the rest are cumulated to the body
IF rs_tag-message IS INITIAL.
rs_tag-message = <lv_string>.
ELSE.
IF rs_tag-body IS NOT INITIAL.
rs_tag-body = rs_tag-body && zif_abapgit_definitions=>c_newline.
ENDIF.
rs_tag-body = rs_tag-body && <lv_string>.
ENDIF.
ENDCASE.
ENDLOOP.
ENDMETHOD.
METHOD decode_tree.
CONSTANTS: lc_sha_length TYPE i VALUE 20,
lc_null TYPE x VALUE '00'.
DATA: lv_xstring TYPE xstring,
lv_chmod TYPE zif_abapgit_definitions=>ty_chmod,
lv_name TYPE string,
lv_string TYPE string,
lv_len TYPE i,
lv_offset TYPE i,
lv_cursor TYPE i,
lv_match TYPE i,
ls_node TYPE ty_node.
DO.
FIND FIRST OCCURRENCE OF lc_null IN SECTION OFFSET lv_cursor OF iv_data
IN BYTE MODE MATCH OFFSET lv_match.
IF sy-subrc <> 0.
EXIT.
ENDIF.
lv_len = lv_match - lv_cursor.
lv_xstring = iv_data+lv_cursor(lv_len).
lv_string = zcl_abapgit_convert=>xstring_to_string_utf8( lv_xstring ).
SPLIT lv_string AT space INTO lv_chmod lv_name.
CLEAR ls_node.
ls_node-chmod = lv_chmod.
IF ls_node-chmod <> zif_abapgit_definitions=>c_chmod-dir
AND ls_node-chmod <> zif_abapgit_definitions=>c_chmod-file
AND ls_node-chmod <> zif_abapgit_definitions=>c_chmod-executable.
zcx_abapgit_exception=>raise( 'Unknown chmod' ).
ENDIF.
lv_offset = lv_match + 1.
ls_node-name = lv_name.
ls_node-sha1 = iv_data+lv_offset(lc_sha_length).
TRANSLATE ls_node-sha1 TO LOWER CASE.
APPEND ls_node TO rt_nodes.
lv_cursor = lv_match + 1 + lc_sha_length.
ENDDO.
ENDMETHOD.
METHOD delta.
CONSTANTS: lc_1 TYPE x VALUE '01',
lc_2 TYPE x VALUE '02',
lc_4 TYPE x VALUE '04',
lc_8 TYPE x VALUE '08',
lc_16 TYPE x VALUE '10',
lc_32 TYPE x VALUE '20',
lc_64 TYPE x VALUE '40',
lc_128 TYPE x VALUE '80'.
DEFINE _eat_byte.
lv_x = lv_delta(1).
lv_delta = lv_delta+1.
END-OF-DEFINITION.
DATA: lv_delta TYPE xstring,
lv_base TYPE xstring,
lv_result TYPE xstring,
lv_offset TYPE i,
lv_sha1 TYPE zif_abapgit_definitions=>ty_sha1,
ls_object LIKE LINE OF ct_objects,
lv_len TYPE i,
lv_org TYPE x,
lv_x TYPE x.
FIELD-SYMBOLS: <ls_object> LIKE LINE OF ct_objects.
lv_delta = is_object-data.
READ TABLE ct_objects ASSIGNING <ls_object>
WITH KEY sha COMPONENTS sha1 = is_object-sha1.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Base not found, { is_object-sha1 }| ).
ELSEIF <ls_object>-type = zif_abapgit_definitions=>c_type-ref_d.
zcx_abapgit_exception=>raise( 'Delta, base eq delta' ).
ENDIF.
lv_base = <ls_object>-data.
delta_header( CHANGING cv_delta = lv_delta ).
delta_header( CHANGING cv_delta = lv_delta ).
WHILE xstrlen( lv_delta ) > 0.
_eat_byte.
lv_org = lv_x.
IF lv_x BIT-AND lc_128 = lc_128. " MSB = 1
lv_offset = 0.
IF lv_org BIT-AND lc_1 = lc_1.
_eat_byte.
lv_offset = lv_x.
ENDIF.
IF lv_org BIT-AND lc_2 = lc_2.
_eat_byte.
lv_offset = lv_offset + lv_x * 256.
ENDIF.
IF lv_org BIT-AND lc_4 = lc_4.
_eat_byte.
lv_offset = lv_offset + lv_x * 65536.
ENDIF.
IF lv_org BIT-AND lc_8 = lc_8.
_eat_byte.
lv_offset = lv_offset + lv_x * 16777216. " hmm, overflow?
ENDIF.
lv_len = 0.
IF lv_org BIT-AND lc_16 = lc_16.
_eat_byte.
lv_len = lv_x.
ENDIF.
IF lv_org BIT-AND lc_32 = lc_32.
_eat_byte.
lv_len = lv_len + lv_x * 256.
ENDIF.
IF lv_org BIT-AND lc_64 = lc_64.
_eat_byte.
lv_len = lv_len + lv_x * 65536.
ENDIF.
IF lv_len = 0.
lv_len = 65536.
ENDIF.
CONCATENATE lv_result lv_base+lv_offset(lv_len)
INTO lv_result IN BYTE MODE.
ELSE. " lv_bitbyte(1) = '0'
lv_len = lv_x.
CONCATENATE lv_result lv_delta(lv_len) INTO lv_result IN BYTE MODE.
lv_delta = lv_delta+lv_len.
ENDIF.
ENDWHILE.
lv_sha1 = zcl_abapgit_hash=>sha1( iv_type = <ls_object>-type iv_data = lv_result ).
CLEAR ls_object.
ls_object-sha1 = lv_sha1.
ls_object-type = <ls_object>-type.
ls_object-data = lv_result.
ls_object-index = <ls_object>-index. "Retain sort index
APPEND ls_object TO ct_objects.
ENDMETHOD.
METHOD delta_header.
DATA: lv_bitbyte TYPE zif_abapgit_definitions=>ty_bitbyte,
lv_bits TYPE string,
lv_x TYPE x.
lv_bits = ''.
DO.
lv_x = cv_delta(1).
cv_delta = cv_delta+1.
lv_bitbyte = zcl_abapgit_convert=>x_to_bitbyte( lv_x ).
CONCATENATE lv_bitbyte+1 lv_bits INTO lv_bits.
IF lv_bitbyte(1) = '0'.
EXIT. " current loop
ENDIF.
ENDDO.
ev_header = zcl_abapgit_convert=>bitbyte_to_int( lv_bits ).
ENDMETHOD.
METHOD encode.
DATA: lv_sha1 TYPE x LENGTH 20,
lv_adler32 TYPE zif_abapgit_definitions=>ty_adler32,
lv_compressed TYPE xstring,
lv_xstring TYPE xstring,
lo_progress TYPE REF TO zcl_abapgit_progress,
lv_objects_total TYPE i.
FIELD-SYMBOLS: <ls_object> LIKE LINE OF it_objects.
rv_data = c_pack_start.
CONCATENATE rv_data c_version INTO rv_data IN BYTE MODE.
lv_xstring = zcl_abapgit_convert=>int_to_xstring4( lines( it_objects ) ).
CONCATENATE rv_data lv_xstring INTO rv_data IN BYTE MODE.
lv_objects_total = lines( it_objects ).
CREATE OBJECT lo_progress
EXPORTING
iv_total = lv_objects_total.
LOOP AT it_objects ASSIGNING <ls_object>.
IF sy-tabix MOD 200 = 0.
lo_progress->show(
iv_current = sy-tabix
iv_text = |Encoding objects ( { sy-tabix } of { lv_objects_total } )| ).
ENDIF.
lv_xstring = type_and_length(
iv_type = <ls_object>-type
iv_length = xstrlen( <ls_object>-data ) ).
CONCATENATE rv_data lv_xstring INTO rv_data IN BYTE MODE.
cl_abap_gzip=>compress_binary(
EXPORTING
raw_in = <ls_object>-data
IMPORTING
gzip_out = lv_compressed ).
CONCATENATE rv_data c_zlib lv_compressed INTO rv_data IN BYTE MODE.
IF NOT <ls_object>-adler32 IS INITIAL.
lv_adler32 = <ls_object>-adler32.
ELSE.
lv_adler32 = zcl_abapgit_hash=>adler32( <ls_object>-data ).
ENDIF.
CONCATENATE rv_data lv_adler32 INTO rv_data IN BYTE MODE.
ENDLOOP.
lv_sha1 = to_upper( zcl_abapgit_hash=>sha1_raw( rv_data ) ).
CONCATENATE rv_data lv_sha1 INTO rv_data IN BYTE MODE.
ENDMETHOD.
METHOD encode_commit.
DATA: lv_string TYPE string,
lv_tmp TYPE string,
lv_tree_lower TYPE string,
lv_parent_lower TYPE string.
lv_tree_lower = is_commit-tree.
TRANSLATE lv_tree_lower TO LOWER CASE.
lv_string = ''.
CONCATENATE 'tree' lv_tree_lower INTO lv_tmp SEPARATED BY space. "#EC NOTEXT
CONCATENATE lv_string lv_tmp zif_abapgit_definitions=>c_newline INTO lv_string.
IF NOT is_commit-parent IS INITIAL.
lv_parent_lower = is_commit-parent.
TRANSLATE lv_parent_lower TO LOWER CASE.
CONCATENATE 'parent' lv_parent_lower
INTO lv_tmp SEPARATED BY space. "#EC NOTEXT
CONCATENATE lv_string lv_tmp zif_abapgit_definitions=>c_newline INTO lv_string.
ENDIF.
IF NOT is_commit-parent2 IS INITIAL.
lv_parent_lower = is_commit-parent2.
TRANSLATE lv_parent_lower TO LOWER CASE.
CONCATENATE 'parent' lv_parent_lower
INTO lv_tmp SEPARATED BY space. "#EC NOTEXT
CONCATENATE lv_string lv_tmp zif_abapgit_definitions=>c_newline INTO lv_string.
ENDIF.
CONCATENATE 'author' is_commit-author
INTO lv_tmp SEPARATED BY space. "#EC NOTEXT
CONCATENATE lv_string lv_tmp zif_abapgit_definitions=>c_newline INTO lv_string.
CONCATENATE 'committer' is_commit-committer
INTO lv_tmp SEPARATED BY space. "#EC NOTEXT
CONCATENATE lv_string lv_tmp zif_abapgit_definitions=>c_newline INTO lv_string.
CONCATENATE lv_string zif_abapgit_definitions=>c_newline is_commit-body INTO lv_string.
rv_data = zcl_abapgit_convert=>string_to_xstring_utf8( lv_string ).
ENDMETHOD.
METHOD encode_tag.
DATA: lv_string TYPE string,
lv_time TYPE zcl_abapgit_time=>ty_unixtime.
lv_time = zcl_abapgit_time=>get( ).
lv_string = |object { is_tag-object }{ zif_abapgit_definitions=>c_newline }|
&& |type { is_tag-type }{ zif_abapgit_definitions=>c_newline }|
&& |tag { zcl_abapgit_tag=>remove_tag_prefix( is_tag-tag ) }{ zif_abapgit_definitions=>c_newline }|
&& |tagger { is_tag-tagger_name } <{ is_tag-tagger_email }> { lv_time }|
&& |{ zif_abapgit_definitions=>c_newline }|
&& |{ zif_abapgit_definitions=>c_newline }|
&& |{ is_tag-message }|.
rv_data = zcl_abapgit_convert=>string_to_xstring_utf8( lv_string ).
ENDMETHOD.
METHOD encode_tree.
CONSTANTS: lc_null TYPE x VALUE '00'.
DATA: lv_string TYPE string,
lt_nodes LIKE it_nodes,
lv_hex20 TYPE x LENGTH 20,
lv_xstring TYPE xstring.
FIELD-SYMBOLS: <ls_node> LIKE LINE OF it_nodes.
lt_nodes = sort_tree( it_nodes ).
LOOP AT lt_nodes ASSIGNING <ls_node>.
ASSERT NOT <ls_node>-chmod IS INITIAL.
ASSERT NOT <ls_node>-name IS INITIAL.
ASSERT NOT <ls_node>-sha1 IS INITIAL.
CONCATENATE <ls_node>-chmod <ls_node>-name INTO lv_string SEPARATED BY space.
lv_xstring = zcl_abapgit_convert=>string_to_xstring_utf8( lv_string ).
lv_hex20 = to_upper( <ls_node>-sha1 ).
CONCATENATE rv_data lv_xstring lc_null lv_hex20 INTO rv_data IN BYTE MODE.
ENDLOOP.
ENDMETHOD.
METHOD get_length.
DATA: lv_x TYPE x,
lv_length_bits TYPE string,
lv_bitbyte TYPE zif_abapgit_definitions=>ty_bitbyte.
lv_x = cv_data(1).
lv_bitbyte = zcl_abapgit_convert=>x_to_bitbyte( lv_x ).
cv_data = cv_data+1.
lv_length_bits = lv_bitbyte+4.
WHILE lv_bitbyte(1) <> '0'.
lv_x = cv_data(1).
lv_bitbyte = zcl_abapgit_convert=>x_to_bitbyte( lv_x ).
cv_data = cv_data+1.
CONCATENATE lv_bitbyte+1 lv_length_bits INTO lv_length_bits.
ENDWHILE.
ev_length = zcl_abapgit_convert=>bitbyte_to_int( lv_length_bits ).
ENDMETHOD.
METHOD get_type.
CONSTANTS: lc_mask TYPE x VALUE 112.
DATA: lv_xtype TYPE x.
lv_xtype = iv_x BIT-AND lc_mask.
CASE lv_xtype.
WHEN 16.
rv_type = zif_abapgit_definitions=>c_type-commit.
WHEN 32.
rv_type = zif_abapgit_definitions=>c_type-tree.
WHEN 48.
rv_type = zif_abapgit_definitions=>c_type-blob.
WHEN 64.
rv_type = zif_abapgit_definitions=>c_type-tag.
WHEN 112.
rv_type = zif_abapgit_definitions=>c_type-ref_d.
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'Todo, unknown type' ).
ENDCASE.
ENDMETHOD.
METHOD sort_tree.
TYPES: BEGIN OF ty_sort,
sort TYPE string,
node TYPE ty_node,
END OF ty_sort.
DATA: lt_sort TYPE STANDARD TABLE OF ty_sort WITH DEFAULT KEY.
FIELD-SYMBOLS: <ls_sort> LIKE LINE OF lt_sort,
<ls_node> LIKE LINE OF it_nodes.
LOOP AT it_nodes ASSIGNING <ls_node>.
APPEND INITIAL LINE TO lt_sort ASSIGNING <ls_sort>.
IF <ls_node>-chmod = zif_abapgit_definitions=>c_chmod-dir.
CONCATENATE <ls_node>-name '/' INTO <ls_sort>-sort.
ELSE.
<ls_sort>-sort = <ls_node>-name.
ENDIF.
<ls_sort>-node = <ls_node>.
ENDLOOP.
SORT lt_sort BY sort ASCENDING.
LOOP AT lt_sort ASSIGNING <ls_sort>.
APPEND <ls_sort>-node TO rt_nodes.
ENDLOOP.
ENDMETHOD.
METHOD type_and_length.
DATA: lv_type TYPE i,
lv_length TYPE i,
lv_hex TYPE x LENGTH 1.
CASE iv_type.
WHEN zif_abapgit_definitions=>c_type-commit.
lv_type = 16.
WHEN zif_abapgit_definitions=>c_type-tree.
lv_type = 32.
WHEN zif_abapgit_definitions=>c_type-blob.
lv_type = 48.
WHEN zif_abapgit_definitions=>c_type-tag.
lv_type = 64.
WHEN zif_abapgit_definitions=>c_type-ref_d.
lv_type = 112.
WHEN OTHERS.
zcx_abapgit_exception=>raise( 'Unexpected object type while encoding pack' ).
ENDCASE.
lv_length = iv_length.
IF lv_length > 15.
lv_hex = 128.
ENDIF.
lv_hex = lv_hex + lv_type + lv_length MOD 16.
rv_xstring = lv_hex.
lv_length = lv_length DIV 16.
WHILE lv_length >= 128.
lv_hex = 128 + lv_length MOD 128.
CONCATENATE rv_xstring lv_hex INTO rv_xstring IN BYTE MODE.
lv_length = lv_length DIV 128.
ENDWHILE.
IF lv_length > 0.
lv_hex = lv_length.
CONCATENATE rv_xstring lv_hex INTO rv_xstring IN BYTE MODE.
ENDIF.
ENDMETHOD.
METHOD zlib_decompress.
DATA: ls_data TYPE zcl_abapgit_zlib=>ty_decompress,
lv_compressed_len TYPE i,
lv_adler32 TYPE zif_abapgit_definitions=>ty_adler32.
ls_data = zcl_abapgit_zlib=>decompress( cv_data ).
lv_compressed_len = ls_data-compressed_len.
cv_decompressed = ls_data-raw.
IF lv_compressed_len IS INITIAL.
zcx_abapgit_exception=>raise( 'Decompression falied :o/' ).
ENDIF.
cv_data = cv_data+lv_compressed_len.
lv_adler32 = zcl_abapgit_hash=>adler32( cv_decompressed ).
IF cv_data(4) <> lv_adler32.
cv_data = cv_data+1.
ENDIF.
IF cv_data(4) <> lv_adler32.
cv_data = cv_data+1.
ENDIF.
IF cv_data(4) <> lv_adler32.
zcx_abapgit_exception=>raise( 'Wrong Adler checksum' ).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_GIT_BRANCH_LIST IMPLEMENTATION.
METHOD complete_heads_branch_name.
IF iv_branch_name CP 'refs/heads/*'.
rv_name = iv_branch_name.
ELSE.
rv_name = 'refs/heads/' && iv_branch_name.
ENDIF.
ENDMETHOD.
METHOD constructor.
parse_branch_list(
EXPORTING iv_data = iv_data
IMPORTING et_list = me->mt_branches
ev_head_symref = me->mv_head_symref ).
ENDMETHOD.
METHOD find_by_name.
IF iv_branch_name IS INITIAL.
zcx_abapgit_exception=>raise( 'Branch name empty' ).
ENDIF.
IF iv_branch_name CP |refs/tags/*|.
rs_branch = find_tag_by_name( iv_branch_name ).
ELSE.
READ TABLE mt_branches INTO rs_branch
WITH KEY name = iv_branch_name.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( |Branch not found: { iv_branch_name }| ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD find_tag_by_name.
DATA: lv_branch_name TYPE string.
lv_branch_name = iv_branch_name && '^{}'.
READ TABLE mt_branches INTO rs_branch
WITH KEY name = lv_branch_name.
IF sy-subrc <> 0.
READ TABLE mt_branches INTO rs_branch
WITH KEY name = iv_branch_name.
IF sy-subrc <> 0.
zcx_abapgit_exception=>raise( 'Branch not found' ).
ENDIF.
ENDIF.
ENDMETHOD.
METHOD get_branches_only.
FIELD-SYMBOLS <ls_branch> LIKE LINE OF mt_branches.
LOOP AT mt_branches ASSIGNING <ls_branch>.
IF <ls_branch>-type = zif_abapgit_definitions=>c_git_branch_type-branch.
APPEND <ls_branch> TO rt_branches.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD get_display_name.
rv_display_name = iv_branch_name.
IF rv_display_name CP 'refs/heads/*'.
REPLACE FIRST OCCURRENCE OF 'refs/heads/' IN rv_display_name WITH ''.
ELSEIF rv_display_name CP 'refs/tags/*'.
REPLACE FIRST OCCURRENCE OF 'refs/' IN rv_display_name WITH ''.
ENDIF.
ENDMETHOD.
METHOD get_head.
IF mv_head_symref IS NOT INITIAL.
rs_branch = find_by_name( mv_head_symref ).
ELSE.
rs_branch = find_by_name( zif_abapgit_definitions=>c_head_name ).
ENDIF.
ENDMETHOD.
METHOD get_head_symref.
rv_head_symref = mv_head_symref.
ENDMETHOD.
METHOD get_tags_only.
FIELD-SYMBOLS <ls_branch> LIKE LINE OF mt_branches.
LOOP AT mt_branches ASSIGNING <ls_branch>
WHERE type = zif_abapgit_definitions=>c_git_branch_type-lightweight_tag
OR type = zif_abapgit_definitions=>c_git_branch_type-annotated_tag.
APPEND <ls_branch> TO rt_tags.
ENDLOOP.
ENDMETHOD.
METHOD get_type.
DATA: lv_annotated_tag_with_suffix TYPE string.
FIELD-SYMBOLS: <lv_result> TYPE LINE OF stringtab.
rv_type = zif_abapgit_definitions=>c_git_branch_type-other.
IF iv_branch_name CP 'refs/heads/*' OR iv_branch_name = zif_abapgit_definitions=>c_head_name.
rv_type = zif_abapgit_definitions=>c_git_branch_type-branch.
RETURN.
ENDIF.
IF iv_branch_name CP 'refs/tags/*'.
lv_annotated_tag_with_suffix = iv_branch_name && '^{}'.
READ TABLE it_result ASSIGNING <lv_result>
INDEX iv_current_row_index + 1.
IF sy-subrc = 0 AND <lv_result> CP '*' && lv_annotated_tag_with_suffix.
rv_type = zif_abapgit_definitions=>c_git_branch_type-annotated_tag.
ELSE.
rv_type = zif_abapgit_definitions=>c_git_branch_type-lightweight_tag.
ENDIF.
ENDIF.
ENDMETHOD.
METHOD is_ignored.
IF iv_branch_name = 'refs/heads/gh-pages'. " Github pages
rv_ignore = abap_true.
ENDIF.
IF iv_branch_name CP 'refs/pull/*'
OR iv_branch_name CP 'refs/merge-requests/*'
OR iv_branch_name CP 'refs/keep-around/*'
OR iv_branch_name CP 'refs/tmp/*'.
rv_ignore = abap_true.
ENDIF.
ENDMETHOD.
METHOD normalize_branch_name.
rv_name = iv_branch_name. " Force convert to string
REPLACE ALL OCCURRENCES OF ` ` IN rv_name WITH '-'. " Disallow space in branch name
ENDMETHOD.
METHOD parse_branch_list.
DATA: lt_result TYPE TABLE OF string,
lv_hash TYPE zif_abapgit_definitions=>ty_sha1,
lv_name TYPE string,
lv_head_params TYPE string,
lv_char TYPE c,
lv_data LIKE LINE OF lt_result,
lv_current_row_index TYPE syst-tabix.
FIELD-SYMBOLS: <ls_branch> LIKE LINE OF et_list.
CLEAR: et_list, ev_head_symref.
SPLIT iv_data AT zif_abapgit_definitions=>c_newline INTO TABLE lt_result.
LOOP AT lt_result INTO lv_data.
lv_current_row_index = sy-tabix.
IF sy-tabix = 1.
CONTINUE. " current loop
ELSEIF sy-tabix = 2 AND strlen( lv_data ) > 49.
lv_hash = lv_data+8.
lv_name = lv_data+49.
lv_char = zcl_abapgit_git_utils=>get_null( ).
SPLIT lv_name AT lv_char INTO lv_name lv_head_params.
ev_head_symref = parse_head_params( lv_head_params ).
ELSEIF sy-tabix > 2 AND strlen( lv_data ) > 45.
lv_hash = lv_data+4.
lv_name = lv_data+45.
ELSEIF sy-tabix = 2 AND strlen( lv_data ) = 8 AND lv_data(8) = '00000000'.
zcx_abapgit_exception=>raise( 'No branches, create branch manually by adding file' ).
ELSE.
CONTINUE.
ENDIF.
CHECK is_ignored( lv_name ) = abap_false.
ASSERT lv_name IS NOT INITIAL.
APPEND INITIAL LINE TO et_list ASSIGNING <ls_branch>.
<ls_branch>-sha1 = lv_hash.
<ls_branch>-name = lv_name.
<ls_branch>-display_name = get_display_name( lv_name ).
<ls_branch>-type = get_type( iv_branch_name = lv_name
it_result = lt_result
iv_current_row_index = lv_current_row_index ).
IF <ls_branch>-name = zif_abapgit_definitions=>c_head_name OR <ls_branch>-name = ev_head_symref.
<ls_branch>-is_head = abap_true.
ENDIF.
ENDLOOP.
ENDMETHOD.
METHOD parse_head_params.
DATA: ls_match TYPE match_result,
ls_submatch TYPE submatch_result.
FIND FIRST OCCURRENCE OF REGEX '\ssymref=HEAD:([^\s]+)' IN iv_data RESULTS ls_match.
READ TABLE ls_match-submatches INTO ls_submatch INDEX 1.
IF sy-subrc IS INITIAL.
rv_head_symref = iv_data+ls_submatch-offset(ls_submatch-length).
ENDIF.
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_BACKGROUND_PUSH_FI IMPLEMENTATION.
METHOD build_comment.
DATA: lt_objects TYPE STANDARD TABLE OF string WITH DEFAULT KEY,
lv_str TYPE string.
FIELD-SYMBOLS: <ls_local> LIKE LINE OF is_files-local.
LOOP AT is_files-local ASSIGNING <ls_local>.
lv_str = |{ <ls_local>-item-obj_type } { <ls_local>-item-obj_name }|.
APPEND lv_str TO lt_objects.
ENDLOOP.
SORT lt_objects AS TEXT.
DELETE ADJACENT DUPLICATES FROM lt_objects.
IF lines( lt_objects ) = 1.
rv_comment = |BG: { lv_str }|.
ELSE.
rv_comment = 'BG: Multiple objects' ##NO_TEXT.
LOOP AT lt_objects INTO lv_str.
CONCATENATE rv_comment zif_abapgit_definitions=>c_newline lv_str INTO rv_comment.
ENDLOOP.
ENDIF.
ENDMETHOD.
METHOD push_fixed.
DATA: ls_comment TYPE zif_abapgit_definitions=>ty_comment,
ls_files TYPE zif_abapgit_definitions=>ty_stage_files,
lo_stage TYPE REF TO zcl_abapgit_stage.
FIELD-SYMBOLS: <ls_local> LIKE LINE OF ls_files-local,
<ls_remote> LIKE LINE OF ls_files-remote.
ls_files = zcl_abapgit_stage_logic=>get( io_repo ).
ASSERT lines( ls_files-local ) > 0
OR lines( ls_files-remote ) > 0.
CREATE OBJECT lo_stage.
LOOP AT ls_files-local ASSIGNING <ls_local>.
mo_log->add_info( |stage: {
<ls_local>-file-path } {
<ls_local>-file-filename }| ).
lo_stage->add( iv_path = <ls_local>-file-path
iv_filename = <ls_local>-file-filename
iv_data = <ls_local>-file-data ).
ENDLOOP.
LOOP AT ls_files-remote ASSIGNING <ls_remote>.
mo_log->add_info( |removed: {
<ls_remote>-path } {
<ls_remote>-filename }| ).
lo_stage->rm( iv_path = <ls_remote>-path
iv_filename = <ls_remote>-filename ).
ENDLOOP.
ls_comment-committer-name = iv_name.
ls_comment-committer-email = iv_email.
ls_comment-comment = build_comment( ls_files ).
io_repo->push( is_comment = ls_comment
io_stage = lo_stage ).
ENDMETHOD.
METHOD zif_abapgit_background~get_description.
rv_description = 'Automatic push, fixed author' ##NO_TEXT.
ENDMETHOD.
METHOD zif_abapgit_background~get_settings.
DATA: ls_setting LIKE LINE OF ct_settings.
READ TABLE ct_settings WITH KEY key = c_settings-name INTO ls_setting.
IF sy-subrc <> 0.
ls_setting-key = c_settings-name.
ls_setting-value = 'foobar'.
APPEND ls_setting TO ct_settings.
ENDIF.
READ TABLE ct_settings WITH KEY key = c_settings-email INTO ls_setting.
IF sy-subrc <> 0.
ls_setting-key = c_settings-email.
ls_setting-value = 'foobar@localhost'.
APPEND ls_setting TO ct_settings.
ENDIF.
ENDMETHOD.
METHOD zif_abapgit_background~run.
DATA: ls_files TYPE zif_abapgit_definitions=>ty_stage_files,
ls_setting LIKE LINE OF it_settings,
lv_name TYPE string,
lv_email TYPE string.
mo_log = io_log.
ls_files = zcl_abapgit_stage_logic=>get( io_repo ).
IF lines( ls_files-local ) = 0 AND lines( ls_files-remote ) = 0.
io_log->add_info( 'Nothing to stage' ).
RETURN.
ENDIF.
READ TABLE it_settings WITH KEY key = c_settings-name INTO ls_setting. "#EC CI_SUBRC
lv_name = ls_setting-value.
READ TABLE it_settings WITH KEY key = c_settings-email INTO ls_setting. "#EC CI_SUBRC
lv_email = ls_setting-value.
push_fixed(
io_repo = io_repo
iv_name = lv_name
iv_email = lv_email ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_BACKGROUND_PUSH_AU IMPLEMENTATION.
METHOD build_comment.
DATA: lt_objects TYPE STANDARD TABLE OF string WITH DEFAULT KEY,
lv_str TYPE string.
FIELD-SYMBOLS: <ls_local> LIKE LINE OF is_files-local.
LOOP AT is_files-local ASSIGNING <ls_local>.
lv_str = |{ <ls_local>-item-obj_type } { <ls_local>-item-obj_name }|.
APPEND lv_str TO lt_objects.
ENDLOOP.
SORT lt_objects AS TEXT.
DELETE ADJACENT DUPLICATES FROM lt_objects.
IF lines( lt_objects ) = 1.
rv_comment = |BG: { lv_str }|.
ELSE.
rv_comment = 'BG: Multiple objects' ##NO_TEXT.
LOOP AT lt_objects INTO lv_str.
CONCATENATE rv_comment zif_abapgit_definitions=>c_newline lv_str INTO rv_comment.
ENDLOOP.
ENDIF.
ENDMETHOD.
METHOD determine_user_details.
DATA: lo_user_master_record TYPE REF TO zcl_abapgit_user_master_record.
lo_user_master_record = zcl_abapgit_user_master_record=>get_instance( iv_changed_by ).
rs_user-name = lo_user_master_record->get_name( ).
rs_user-email = lo_user_master_record->get_email( ).
IF rs_user-email IS INITIAL.
rs_user-email = |{ iv_changed_by }@localhost|.
ENDIF.
IF rs_user-name IS INITIAL.
rs_user-name = iv_changed_by.
ENDIF.
ENDMETHOD.
METHOD push_auto.
TYPES: BEGIN OF ty_changed,
filename TYPE string,
path TYPE string,
changed_by TYPE xubname,
END OF ty_changed.
DATA: ls_comment TYPE zif_abapgit_definitions=>ty_comment,
ls_files TYPE zif_abapgit_definitions=>ty_stage_files,
lt_changed TYPE STANDARD TABLE OF ty_changed WITH DEFAULT KEY,
lt_users TYPE STANDARD TABLE OF xubname WITH DEFAULT KEY,
ls_user_files LIKE ls_files,
lv_changed_by LIKE LINE OF lt_users,
lo_stage TYPE REF TO zcl_abapgit_stage.
FIELD-SYMBOLS: <ls_changed> LIKE LINE OF lt_changed,
<ls_remote> LIKE LINE OF ls_files-remote,
<ls_local> LIKE LINE OF ls_files-local.
ls_files = zcl_abapgit_stage_logic=>get( io_repo ).
LOOP AT ls_files-local ASSIGNING <ls_local>.
lv_changed_by = zcl_abapgit_objects=>changed_by( <ls_local>-item ).
APPEND lv_changed_by TO lt_users.
APPEND INITIAL LINE TO lt_changed ASSIGNING <ls_changed>.
<ls_changed>-changed_by = lv_changed_by.
<ls_changed>-filename = <ls_local>-file-filename.
<ls_changed>-path = <ls_local>-file-path.
ENDLOOP.
SORT lt_users ASCENDING.
DELETE ADJACENT DUPLICATES FROM lt_users.
LOOP AT lt_users INTO lv_changed_by.
CLEAR: ls_comment.
ls_comment-committer = determine_user_details( lv_changed_by ).
CREATE OBJECT lo_stage.
CLEAR ls_user_files.
LOOP AT ls_files-local ASSIGNING <ls_local>.
READ TABLE lt_changed WITH KEY
path = <ls_local>-file-path
filename = <ls_local>-file-filename
changed_by = lv_changed_by
TRANSPORTING NO FIELDS.
IF sy-subrc = 0.
mo_log->add_info( |stage: {
ls_comment-committer-name } {
<ls_local>-file-path } {
<ls_local>-file-filename }| ).
lo_stage->add( iv_path = <ls_local>-file-path
iv_filename = <ls_local>-file-filename
iv_data = <ls_local>-file-data ).
APPEND <ls_local> TO ls_user_files-local.
LOOP AT ls_files-remote ASSIGNING <ls_remote>
WHERE filename = <ls_local>-file-filename
AND path <> <ls_local>-file-path
AND filename <> 'package.devc.xml'.
mo_log->add_info( |rm: {
<ls_remote>-path } {
<ls_remote>-filename }| ).
lo_stage->rm(
iv_path = <ls_remote>-path
iv_filename = <ls_remote>-filename ).
EXIT. " assumption: only one file
ENDLOOP.
ENDIF.
ENDLOOP.
ls_comment-comment = build_comment( ls_user_files ).
io_repo->push( is_comment = ls_comment
io_stage = lo_stage ).
ENDLOOP.
IF lines( ls_files-remote ) > 0.
push_deletions( io_repo = io_repo
is_files = ls_files ).
ENDIF.
ENDMETHOD.
METHOD push_deletions.
DATA: lo_stage TYPE REF TO zcl_abapgit_stage,
ls_comment TYPE zif_abapgit_definitions=>ty_comment.
FIELD-SYMBOLS: <ls_remote> LIKE LINE OF is_files-remote.
ASSERT lines( is_files-remote ) > 0.
CREATE OBJECT lo_stage.
LOOP AT is_files-remote ASSIGNING <ls_remote>.
mo_log->add_info( |removed: {
<ls_remote>-path } {
<ls_remote>-filename }| ).
lo_stage->rm( iv_path = <ls_remote>-path
iv_filename = <ls_remote>-filename ).
ENDLOOP.
ls_comment-committer-name = 'Deletion' ##NO_TEXT.
ls_comment-committer-email = 'deletion@localhost'.
ls_comment-comment = build_comment( is_files ).
io_repo->push( is_comment = ls_comment
io_stage = lo_stage ).
ENDMETHOD.
METHOD zif_abapgit_background~get_description.
rv_description = 'Automatic push, auto author' ##NO_TEXT.
ENDMETHOD.
METHOD zif_abapgit_background~get_settings.
RETURN.
ENDMETHOD.
METHOD zif_abapgit_background~run.
DATA: ls_files TYPE zif_abapgit_definitions=>ty_stage_files.
mo_log = io_log.
ls_files = zcl_abapgit_stage_logic=>get( io_repo ).
IF lines( ls_files-local ) = 0 AND lines( ls_files-remote ) = 0.
io_log->add_info( 'Nothing to stage' ) ##NO_TEXT.
RETURN.
ENDIF.
push_auto( io_repo ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_BACKGROUND_PULL IMPLEMENTATION.
METHOD zif_abapgit_background~get_description.
rv_description = 'Automatic pull' ##NO_TEXT.
ENDMETHOD.
METHOD zif_abapgit_background~get_settings.
RETURN.
ENDMETHOD.
METHOD zif_abapgit_background~run.
DATA: ls_checks TYPE zif_abapgit_definitions=>ty_deserialize_checks.
io_repo->deserialize( ls_checks ).
ENDMETHOD.
ENDCLASS.
CLASS ZCL_ABAPGIT_BACKGROUND IMPLEMENTATION.
METHOD list_methods.
DATA: ls_method LIKE LINE OF rt_methods,
ls_key TYPE seoclskey,
lt_implementing TYPE seor_implementing_keys,
ls_implementing LIKE LINE OF lt_implementing.
FIELD-SYMBOLS: <ls_method> LIKE LINE OF rt_methods.
ls_method-class = 'ZCL_ABAPGIT_BACKGROUND_PULL'.
INSERT ls_method INTO TABLE rt_methods.
ls_method-class = 'ZCL_ABAPGIT_BACKGROUND_PUSH_AU'.
INSERT ls_method INTO TABLE rt_methods.
ls_method-class = 'ZCL_ABAPGIT_BACKGROUND_PUSH_FI'.
INSERT ls_method INTO TABLE rt_methods.
ls_key-clsname = 'ZIF_ABAPGIT_BACKGROUND'.
CALL FUNCTION 'SEO_INTERFACE_IMPLEM_GET_ALL'
EXPORTING
intkey = ls_key
IMPORTING
impkeys = lt_implementing
EXCEPTIONS
not_existing = 1
OTHERS = 2 ##FM_SUBRC_OK.
LOOP AT lt_implementing INTO ls_implementing.
ls_method-class = ls_implementing-clsname.
INSERT ls_method INTO TABLE rt_methods.
ENDLOOP.
LOOP AT rt_methods ASSIGNING <ls_method>.
CALL METHOD (<ls_method>-class)=>zif_abapgit_background~get_description
RECEIVING
rv_description = <ls_method>-description.
ENDLOOP.
ENDMETHOD.
METHOD run.
CONSTANTS: lc_enq_type TYPE c LENGTH 12 VALUE 'BACKGROUND'.
DATA: lo_per TYPE REF TO zcl_abapgit_persist_background,
lo_repo TYPE REF TO zcl_abapgit_repo_online,
lt_list TYPE zcl_abapgit_persist_background=>tt_background,
li_background TYPE REF TO zif_abapgit_background,
lo_log TYPE REF TO zcl_abapgit_log,
lv_repo_name TYPE string.
FIELD-SYMBOLS: <ls_list> LIKE LINE OF lt_list.
CALL FUNCTION 'ENQUEUE_EZABAPGIT'
EXPORTING
mode_zabapgit = 'E'
type = lc_enq_type
_scope = '3'
EXCEPTIONS
foreign_lock = 1
system_failure = 2
OTHERS = 3.
IF sy-subrc <> 0.
WRITE: / 'Another intance of the program is already running' ##NO_TEXT.
RETURN.
ENDIF.
CREATE OBJECT lo_per.
lt_list = lo_per->list( ).
WRITE: / 'Background mode' ##NO_TEXT.
LOOP AT lt_list ASSIGNING <ls_list>.
lo_repo ?= zcl_abapgit_repo_srv=>get_instance( )->get( <ls_list>-key ).
lv_repo_name = lo_repo->get_name( ).
WRITE: / <ls_list>-method, lv_repo_name.
zcl_abapgit_login_manager=>set(
iv_uri = lo_repo->get_url( )
iv_username = <ls_list>-username
iv_password = <ls_list>-password ).
CREATE OBJECT lo_log.
CREATE OBJECT li_background TYPE (<ls_list>-method).
li_background->run(
io_repo = lo_repo
io_log = lo_log
it_settings = <ls_list>-settings ).
lo_log->write( ).
ENDLOOP.
IF lines( lt_list ) = 0.
WRITE: / 'Nothing configured' ##NO_TEXT.
ENDIF.
CALL FUNCTION 'DEQUEUE_EZABAPGIT'
EXPORTING
type = lc_enq_type.
ENDMETHOD.
ENDCLASS.
TABLES sscrfields.
SELECTION-SCREEN BEGIN OF SCREEN 1002 TITLE s_title.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(10) s_url FOR FIELD p_url.
PARAMETERS: p_url TYPE string LOWER CASE VISIBLE LENGTH 40 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(10) s_user FOR FIELD p_user.
PARAMETERS: p_user TYPE string LOWER CASE VISIBLE LENGTH 40 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN BEGIN OF LINE.
SELECTION-SCREEN COMMENT 1(10) s_pass FOR FIELD p_pass.
PARAMETERS: p_pass TYPE string LOWER CASE VISIBLE LENGTH 40 ##SEL_WRONG.
SELECTION-SCREEN END OF LINE.
SELECTION-SCREEN END OF SCREEN 1002.
CLASS lcl_password_dialog DEFINITION FINAL.
PUBLIC SECTION.
CONSTANTS c_dynnr TYPE char4 VALUE '1002'.
CLASS-METHODS popup
IMPORTING
iv_repo_url TYPE string
CHANGING
cv_user TYPE string
cv_pass TYPE string.
CLASS-METHODS on_screen_init.
CLASS-METHODS on_screen_output.
CLASS-METHODS on_screen_event
IMPORTING
iv_ucomm TYPE syucomm.
PRIVATE SECTION.
CLASS-DATA gv_confirm TYPE abap_bool.
CLASS-METHODS enrich_title_by_hostname
IMPORTING
iv_repo_url TYPE string.
ENDCLASS. "lcl_password_dialog DEFINITION
CLASS lcl_password_dialog IMPLEMENTATION.
METHOD popup.
CLEAR p_pass.
p_url = iv_repo_url.
p_user = cv_user.
gv_confirm = abap_false.
enrich_title_by_hostname( iv_repo_url ).
CALL SELECTION-SCREEN c_dynnr STARTING AT 5 5 ENDING AT 60 8.
IF gv_confirm = abap_true.
cv_user = p_user.
cv_pass = p_pass.
ELSE.
CLEAR: cv_user, cv_pass.
ENDIF.
CLEAR: p_url, p_user, p_pass.
ENDMETHOD. "popup
METHOD on_screen_init.
s_title = 'Login' ##NO_TEXT.
s_url = 'Repo URL' ##NO_TEXT.
s_user = 'User' ##NO_TEXT.
s_pass = 'Password' ##NO_TEXT.
ENDMETHOD. "on_screen_init
METHOD on_screen_output.
DATA lt_ucomm TYPE TABLE OF sy-ucomm.
ASSERT sy-dynnr = c_dynnr.
LOOP AT SCREEN.
IF screen-name = 'P_URL'.
screen-input = '0'.
screen-intensified = '1'.
screen-display_3d = '0'.
MODIFY SCREEN.
ENDIF.
IF screen-name = 'P_PASS'.
screen-invisible = '1'.
MODIFY SCREEN.
ENDIF.
ENDLOOP.
" Program RSSYSTDB, GUI Status %_CSP
PERFORM set_pf_status IN PROGRAM rsdbrunt IF FOUND.
APPEND 'NONE' TO lt_ucomm. "Button Check
APPEND 'SPOS' TO lt_ucomm. "Save as Variant
CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
EXPORTING
p_status = sy-pfkey
TABLES
p_exclude = lt_ucomm.
IF p_user IS NOT INITIAL.
SET CURSOR FIELD 'P_PASS'.
ENDIF.
ENDMETHOD. "on_screen_output
METHOD on_screen_event.
ASSERT sy-dynnr = c_dynnr.
" CRET - F8
" OTHERS - simulate Enter press
CASE iv_ucomm.
WHEN 'CRET'.
gv_confirm = abap_true.
WHEN OTHERS. "TODO REFACTOR !!! A CLUTCH !
" This will work unless any new specific logic appear
" for other commands. The problem is that the password dialog
" does not have Enter event (or I don't know how to activate it ;)
" so Enter issues previous command from previous screen
" But for now this works :) Fortunately Esc produces another flow
gv_confirm = abap_true.
LEAVE TO SCREEN 0.
ENDCASE.
ENDMETHOD. "on_screen_event
METHOD enrich_title_by_hostname.
DATA lv_host TYPE string.
FIND REGEX 'https?://([^/^:]*)' IN iv_repo_url SUBMATCHES lv_host.
IF lv_host IS NOT INITIAL AND lv_host <> space.
CLEAR s_title.
CONCATENATE 'Login:' lv_host INTO s_title IN CHARACTER MODE SEPARATED BY space.
ENDIF.
ENDMETHOD.
ENDCLASS. " lcl_password_dialog IMPLEMENTATION
FORM run.
DATA: lx_exception TYPE REF TO zcx_abapgit_exception,
lv_ind TYPE t000-ccnocliind.
SELECT SINGLE ccnocliind FROM t000 INTO lv_ind
WHERE mandt = sy-mandt.
IF sy-subrc = 0
AND lv_ind <> ' '
AND lv_ind <> '1'. " check changes allowed
WRITE: / 'Wrong client, changes to repository objects not allowed'. "#EC NOTEXT
RETURN.
ENDIF.
TRY.
zcl_abapgit_migrations=>run( ).
PERFORM open_gui.
CATCH zcx_abapgit_exception INTO lx_exception.
MESSAGE lx_exception TYPE 'E'.
ENDTRY.
ENDFORM. "run
FORM open_gui RAISING zcx_abapgit_exception.
IF sy-batch = abap_true.
zcl_abapgit_background=>run( ).
ELSE.
IF zcl_abapgit_persist_settings=>get_instance( )->read( )->get_show_default_repo( ) = abap_false.
" Don't show the last seen repo at startup
zcl_abapgit_persistence_user=>get_instance( )->set_repo_show( || ).
ENDIF.
zcl_abapgit_gui=>get_instance( )->go_home( ).
CALL SELECTION-SCREEN 1001. " trigger screen
ENDIF.
ENDFORM.
FORM branch_popup TABLES tt_fields TYPE zif_abapgit_definitions=>ty_sval_tt
USING pv_code TYPE clike
CHANGING cs_error TYPE svale
cv_show_popup TYPE c
RAISING zcx_abapgit_exception ##called ##needed.
DATA: lx_error TYPE REF TO zcx_abapgit_exception,
li_popups TYPE REF TO zif_abapgit_popups.
TRY.
li_popups = zcl_abapgit_ui_factory=>get_popups( ).
li_popups->branch_popup_callback(
EXPORTING
iv_code = pv_code
CHANGING
ct_fields = tt_fields[]
cs_error = cs_error
cv_show_popup = cv_show_popup ).
CATCH zcx_abapgit_exception INTO lx_error.
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDFORM. "branch_popup
FORM package_popup TABLES tt_fields TYPE zif_abapgit_definitions=>ty_sval_tt
USING pv_code TYPE clike
CHANGING cs_error TYPE svale
cv_show_popup TYPE c
RAISING zcx_abapgit_exception ##called ##needed.
DATA: lx_error TYPE REF TO zcx_abapgit_exception,
li_popups TYPE REF TO zif_abapgit_popups.
TRY.
li_popups = zcl_abapgit_ui_factory=>get_popups( ).
li_popups->package_popup_callback(
EXPORTING
iv_code = pv_code
CHANGING
ct_fields = tt_fields[]
cs_error = cs_error
cv_show_popup = cv_show_popup ).
CATCH zcx_abapgit_exception INTO lx_error.
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDFORM. "package_popup
FORM output.
DATA: lt_ucomm TYPE TABLE OF sy-ucomm,
lx_error TYPE REF TO zcx_abapgit_exception.
PERFORM set_pf_status IN PROGRAM rsdbrunt IF FOUND.
APPEND 'CRET' TO lt_ucomm. "Button Execute
CALL FUNCTION 'RS_SET_SELSCREEN_STATUS'
EXPORTING
p_status = sy-pfkey
TABLES
p_exclude = lt_ucomm.
TRY.
zcl_abapgit_gui=>get_instance( )->focus( ).
CATCH zcx_abapgit_exception INTO lx_error.
MESSAGE lx_error TYPE 'S' DISPLAY LIKE 'E'.
ENDTRY.
ENDFORM.
FORM exit RAISING zcx_abapgit_exception.
CASE sy-ucomm.
WHEN 'CBAC'. "Back
IF zcl_abapgit_gui=>get_instance( )->back( ) IS INITIAL.
LEAVE TO SCREEN 1001.
ENDIF.
ENDCASE.
ENDFORM.
FORM password_popup
USING
iv_repo_url TYPE string
CHANGING
cv_user TYPE string
cv_pass TYPE string.
lcl_password_dialog=>popup(
EXPORTING
iv_repo_url = iv_repo_url
CHANGING
cv_user = cv_user
cv_pass = cv_pass ).
ENDFORM.
INITIALIZATION.
lcl_password_dialog=>on_screen_init( ).
START-OF-SELECTION.
PERFORM run.
AT SELECTION-SCREEN OUTPUT.
IF sy-dynnr = lcl_password_dialog=>c_dynnr.
lcl_password_dialog=>on_screen_output( ).
ELSE.
PERFORM output.
ENDIF.
AT SELECTION-SCREEN ON EXIT-COMMAND.
PERFORM exit.
AT SELECTION-SCREEN.
IF sy-dynnr = lcl_password_dialog=>c_dynnr.
lcl_password_dialog=>on_screen_event( sscrfields-ucomm ).
ENDIF.
|